<template>
  <div class="ansible-audit-container">
    <!-- 星空背景 -->
    <div class="starry-background">
      <div class="stars"></div>
      <div class="stars2"></div>
      <div class="stars3"></div>
    </div>

    <!-- 主要内容区域 -->
    <div class="audit-content">
      <!-- 页面标题 -->
      <div class="page-header glass-effect">
        <div class="header-content">
          <div class="title-section">
            <h1 class="page-title">
              <i class="fa fa-layer-group"></i>
              Docker镜像管理
            </h1>
            <p class="page-subtitle">管理Docker镜像的拉取、删除、构建等操作</p>
          </div>
          <div class="stats-section">
            <div class="stat-card glass-effect">
              <div class="stat-number">{{ statistics?.total_images || 0 }}</div>
              <div class="stat-label">镜像总数</div>
            </div>
            <div class="stat-card glass-effect">
              <div class="stat-number">{{ statistics?.total_size || '0 MB' }}</div>
              <div class="stat-label">总大小</div>
            </div>
            <div class="stat-card glass-effect">
              <div class="stat-number">{{ statistics?.dangling_images || 0 }}</div>
              <div class="stat-label">悬空镜像</div>
            </div>
          </div>
        </div>
      </div>

      <!-- 操作按钮 -->
      <div class="search-filters glass-effect">
        <el-form inline class="search-form">
          <el-form-item>
            <el-select v-model="selectedServer" placeholder="选择Docker服务器" class="server-select">
              <el-option
                v-for="server in dockerServers"
                :key="server.id"
                :label="server.name"
                :value="server.id"
              />
            </el-select>
            <el-button type="primary" @click="refreshImages" class="glass-button refresh-button" :loading="loading">
              <i class="fa fa-refresh"></i>
              刷新镜像
            </el-button>
            <el-button @click="pullImage" class="glass-button add-button">
              <i class="fa fa-download"></i>
              拉取镜像
            </el-button>
            <el-button @click="pushImage" class="glass-button upload-button">
              <i class="fa fa-upload"></i>
              推送镜像
            </el-button>
            <el-button @click="buildImage" class="glass-button sync-button">
              <i class="fa fa-cogs"></i>
              构建镜像
            </el-button>
            <el-button @click="cleanupImages" class="glass-button delete-button">
              <i class="fa fa-trash"></i>
              清理悬空镜像
            </el-button>
          </el-form-item>
        </el-form>
      </div>

      <!-- 镜像列表 -->
      <div class="audit-table-section glass-effect">
        <div class="section-title">
          <i class="fa fa-layer-group"></i>
          Docker镜像列表
        </div>

        <el-table
          :data="images"
          style="width: 100%"
          v-loading="loading"
          row-class-name="audit-row"
          class="audit-table"
        >
          <el-table-column prop="repository" label="仓库" min-width="200">
            <template #default="scope">
              <div class="config-name">
                <i class="fa fa-layer-group"></i>
                {{ scope.row.repository }}
              </div>
            </template>
          </el-table-column>

          <el-table-column prop="tag" label="标签" width="120" />

          <el-table-column prop="id" label="镜像ID" width="150">
            <template #default="scope">
              <span class="image-id">
                {{ scope.row.id ? scope.row.id.substring(0, 12) : '' }}
              </span>
            </template>
          </el-table-column>

          <el-table-column prop="size" label="大小" width="100">
            <template #default="scope">
              <span class="size-text">
                {{ scope.row.size }}
              </span>
            </template>
          </el-table-column>

          <el-table-column prop="created_since" label="创建时间" width="150">
            <template #default="scope">
              <span class="time-text">
                {{ scope.row.created_since }}
              </span>
            </template>
          </el-table-column>

          <el-table-column label="操作" width="580" :show-overflow-tooltip="false">
            <template #default="scope">
              <div class="action-buttons">
                <el-button
                  @click="runContainer(scope.row)"
                  size="small"
                  class="glass-button add-button"
                >
                  <i class="fa fa-play"></i>
                  运行
                </el-button>
                <el-button
                  @click="tagImage(scope.row)"
                  size="small"
                  class="glass-button sync-button"
                >
                  <i class="fa fa-tag"></i>
                  标签
                </el-button>
                <el-button
                  @click="exportImage(scope.row)"
                  size="small"
                  class="glass-button import-button"
                >
                  <i class="fa fa-upload"></i>
                  导出
                </el-button>
                <el-button
                  @click="inspectImage(scope.row)"
                  size="small"
                  class="glass-button info-button"
                >
                  <i class="fa fa-search"></i>
                  详情
                </el-button>
                <el-button
                  @click="deleteImage(scope.row)"
                  size="small"
                  class="glass-button delete-button"
                >
                  <i class="fa fa-trash"></i>
                  删除
                </el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
  </div>

  <!-- 构建镜像对话框 -->
  <el-dialog
    v-model="buildDialogVisible"
    title="构建Docker镜像"
    width="1400px"
    class="glass-dialog"
    :close-on-click-modal="false"
    :destroy-on-close="true"
  >
    <div class="build-image-container">
      <!-- 左侧配置区域 -->
      <div class="build-config-section">
        <div class="dialog-form-glass">
          <el-form :model="buildForm" label-width="100px" class="form-glass">
            <!-- 基础镜像 -->
            <el-form-item label="基础镜像" required>
              <el-select
                v-model="buildForm.base_image"
                class="glass-select"
                style="width: 100%"
                filterable
                allow-create
                placeholder="选择或输入基础镜像"
              >
                <el-option
                  v-for="image in baseImageOptions"
                  :key="image"
                  :label="image"
                  :value="image"
                />
              </el-select>
              <div class="form-tip">选择基础镜像或手动输入</div>
            </el-form-item>

            <!-- 镜像名称 -->
            <el-form-item label="镜像名称" required>
              <el-input
                v-model="buildForm.image_name"
                placeholder="例如: my-app:latest"
                class="glass-input"
              />
              <div class="form-tip">为构建的镜像指定名称和标签</div>
            </el-form-item>

            <!-- 维护者信息 -->
            <el-form-item label="维护者">
              <el-input
                v-model="buildForm.maintainer"
                placeholder="例如: John Doe <john@example.com>"
                class="glass-input"
              />
              <div class="form-tip">镜像维护者信息（MAINTAINER指令，已废弃但仍支持）</div>
            </el-form-item>

            <!-- 标签 -->
            <el-form-item label="镜像标签">
              <div class="labels-container">
                <div
                  v-for="(label, index) in buildForm.labels"
                  :key="index"
                  class="label-item"
                >
                  <el-input
                    v-model="label.key"
                    placeholder="标签名，例如: version"
                    class="glass-input label-key-input"
                  />
                  <span class="label-separator">=</span>
                  <el-input
                    v-model="label.value"
                    placeholder="标签值，例如: 1.0.0"
                    class="glass-input label-value-input"
                  />
                  <el-button
                    @click="removeLabel(index)"
                    class="glass-button delete-button label-remove-btn"
                    size="small"
                    :disabled="buildForm.labels.length === 1"
                  >
                    <i class="fa fa-minus"></i>
                  </el-button>
                </div>
                <el-button
                  @click="addLabel"
                  class="glass-button add-button label-add-btn"
                  size="small"
                >
                  <i class="fa fa-plus"></i>
                  添加标签
                </el-button>
              </div>
              <div class="form-tip">为镜像添加元数据标签（LABEL指令）</div>
            </el-form-item>

            <!-- 环境变量 -->
            <el-form-item label="环境变量">
              <div class="env-vars-container">
                <div
                  v-for="(envVar, index) in buildForm.env_vars"
                  :key="index"
                  class="env-var-item"
                >
                  <el-input
                    v-model="envVar.key"
                    placeholder="变量名，例如: NODE_ENV"
                    class="glass-input env-key-input"
                  />
                  <span class="env-separator">=</span>
                  <el-input
                    v-model="envVar.value"
                    placeholder="变量值，例如: production"
                    class="glass-input env-value-input"
                  />
                  <el-button
                    @click="removeEnvVar(index)"
                    class="glass-button delete-button env-remove-btn"
                    size="small"
                    :disabled="buildForm.env_vars.length === 1"
                  >
                    <i class="fa fa-minus"></i>
                  </el-button>
                </div>
                <el-button
                  @click="addEnvVar"
                  class="glass-button add-button env-add-btn"
                  size="small"
                >
                  <i class="fa fa-plus"></i>
                  添加环境变量
                </el-button>
              </div>
              <div class="form-tip">设置构建时的环境变量（ENV指令）</div>
            </el-form-item>

            <!-- 工作目录 -->
            <el-form-item label="工作目录">
              <el-input
                v-model="buildForm.work_dir"
                placeholder="/app"
                class="glass-input"
              />
              <div class="form-tip">设置容器内的工作目录</div>
            </el-form-item>

            <!-- 文件复制 -->
            <el-form-item label="复制文件">
              <div class="copy-files-container">
                <div
                  v-for="(file, index) in buildForm.copy_files"
                  :key="index"
                  class="copy-file-item"
                >
                  <el-input
                    v-model="file.source"
                    placeholder="源文件路径，例如: app.py"
                    class="glass-input copy-source-input"
                  />
                  <span class="copy-arrow">→</span>
                  <el-input
                    v-model="file.target"
                    placeholder="目标路径，例如: ."
                    class="glass-input copy-target-input"
                  />
                  <el-button
                    @click="removeCopyFile(index)"
                    class="glass-button delete-button copy-remove-btn"
                    size="small"
                    :disabled="buildForm.copy_files.length === 1"
                  >
                    <i class="fa fa-minus"></i>
                  </el-button>
                </div>
                <el-button
                  @click="addCopyFile"
                  class="glass-button add-button copy-add-btn"
                  size="small"
                >
                  <i class="fa fa-plus"></i>
                  添加文件复制
                </el-button>
              </div>
              <div class="form-tip">指定要复制到镜像中的文件（COPY指令）</div>
            </el-form-item>

            <!-- ADD文件 -->
            <el-form-item label="ADD文件">
              <div class="add-files-container">
                <div
                  v-for="(file, index) in buildForm.add_files"
                  :key="index"
                  class="add-file-item"
                >
                  <el-input
                    v-model="file.source"
                    placeholder="源文件路径，例如: app.tar.gz"
                    class="glass-input add-source-input"
                  />
                  <span class="add-arrow">→</span>
                  <el-input
                    v-model="file.target"
                    placeholder="目标路径，例如: /app/"
                    class="glass-input add-target-input"
                  />
                  <el-button
                    @click="removeAddFile(index)"
                    class="glass-button delete-button add-remove-btn"
                    size="small"
                    :disabled="buildForm.add_files.length === 1"
                  >
                    <i class="fa fa-minus"></i>
                  </el-button>
                </div>
                <el-button
                  @click="addAddFile"
                  class="glass-button add-button add-add-btn"
                  size="small"
                >
                  <i class="fa fa-plus"></i>
                  添加ADD文件
                </el-button>
              </div>
              <div class="form-tip">ADD指令支持URL和自动解压缩功能</div>
            </el-form-item>

            <!-- 文件上传 -->
            <el-form-item label="上传文件">
              <div class="file-upload-container">
                <el-upload
                  :before-upload="handleFileUpload"
                  :show-file-list="false"
                  multiple
                  class="glass-upload"
                >
                  <el-button class="glass-button add-button">
                    <i class="fa fa-upload"></i>
                    选择文件
                  </el-button>
                </el-upload>
                <div class="uploaded-files-list">
                  <div
                    v-for="[filename] in uploadedFiles"
                    :key="filename"
                    class="uploaded-file-item"
                  >
                    <i class="fa fa-file"></i>
                    <span class="filename">{{ filename }}</span>
                    <el-button
                      @click="removeUploadedFile(filename)"
                      class="glass-button delete-button file-remove-btn"
                      size="small"
                    >
                      <i class="fa fa-times"></i>
                    </el-button>
                  </div>
                </div>
              </div>
              <div class="form-tip">上传的文件将放在构建上下文中，可在COPY/ADD指令中使用</div>
            </el-form-item>

            <!-- 运行命令 -->
            <el-form-item label="运行命令">
              <div class="run-commands-container">
                <div
                  v-for="(cmd, index) in buildForm.run_commands"
                  :key="index"
                  class="run-command-item"
                >
                  <el-input
                    v-model="buildForm.run_commands[index]"
                    placeholder="例如: pip install -r requirements.txt"
                    class="glass-input run-command-input"
                  />
                  <el-button
                    @click="removeRunCommand(index)"
                    class="glass-button delete-button run-remove-btn"
                    size="small"
                    :disabled="buildForm.run_commands.length === 1"
                  >
                    <i class="fa fa-minus"></i>
                  </el-button>
                </div>
                <el-button
                  @click="addRunCommand"
                  class="glass-button add-button run-add-btn"
                  size="small"
                >
                  <i class="fa fa-plus"></i>
                  添加运行命令
                </el-button>
              </div>
              <div class="form-tip">构建时执行的命令</div>
            </el-form-item>

            <!-- 暴露端口 -->
            <el-form-item label="暴露端口">
              <div class="expose-ports-container">
                <div class="ports-input-row">
                  <el-input
                    v-model="buildForm.new_port"
                    placeholder="端口号，例如: 80"
                    class="glass-input port-input"
                    @keyup.enter="addPort"
                  />
                  <el-button
                    @click="addPort"
                    class="glass-button add-button port-add-btn"
                    size="small"
                  >
                    <i class="fa fa-plus"></i>
                    添加
                  </el-button>
                </div>
                <div class="ports-list">
                  <el-tag
                    v-for="port in buildForm.expose_ports"
                    :key="port"
                    closable
                    @close="removePort(port)"
                    class="port-tag"
                  >
                    {{ port }}
                  </el-tag>
                </div>
              </div>
              <div class="form-tip">容器对外暴露的端口</div>
            </el-form-item>

            <!-- 数据卷 -->
            <el-form-item label="数据卷">
              <div class="volumes-container">
                <div
                  v-for="(volume, index) in buildForm.volumes"
                  :key="index"
                  class="volume-item"
                >
                  <el-input
                    v-model="buildForm.volumes[index]"
                    placeholder="例如: /data"
                    class="glass-input volume-input"
                  />
                  <el-button
                    @click="removeVolume(index)"
                    class="glass-button delete-button volume-remove-btn"
                    size="small"
                    :disabled="buildForm.volumes.length === 1"
                  >
                    <i class="fa fa-minus"></i>
                  </el-button>
                </div>
                <el-button
                  @click="addVolume"
                  class="glass-button add-button volume-add-btn"
                  size="small"
                >
                  <i class="fa fa-plus"></i>
                  添加数据卷
                </el-button>
              </div>
              <div class="form-tip">定义匿名数据卷（VOLUME指令）</div>
            </el-form-item>

            <!-- 入口点 -->
            <el-form-item label="入口点">
              <el-input
                v-model="buildForm.entrypoint_command"
                placeholder='例如: /entrypoint.sh 或 ["/entrypoint.sh", "param"]'
                class="glass-input"
              />
              <div class="form-tip">容器的入口点命令。可以是shell格式或JSON数组格式</div>
            </el-form-item>

            <!-- 启动命令 -->
            <el-form-item label="启动命令">
              <el-input
                v-model="buildForm.cmd_command"
                placeholder='例如: nginx -g "daemon off;" 或 ["nginx", "-g", "daemon off;"]'
                class="glass-input"
              />
              <div class="form-tip">容器启动时执行的命令。可以是shell格式或JSON数组格式</div>
            </el-form-item>
          </el-form>
        </div>
      </div>

      <!-- 右侧预览区域 -->
      <div class="dockerfile-preview-section">
        <div class="preview-header">
          <h4><i class="fa fa-file-code-o"></i> Dockerfile预览</h4>
        </div>
        <div class="dockerfile-content">
          <pre>{{ generatedDockerfile }}</pre>
        </div>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="buildDialogVisible = false" class="glass-button" :disabled="building">
          <i class="fa fa-times"></i>
          取消
        </el-button>
        <el-button @click="submitBuildImage" class="glass-button add-button" :loading="building">
          <i class="fa fa-hammer"></i>
          {{ building ? '构建中...' : '构建镜像' }}
        </el-button>
      </div>
    </template>
  </el-dialog>

  <!-- 构建日志对话框 -->
  <el-dialog
    v-model="buildLogVisible"
    title="镜像构建日志"
    width="900px"
    class="glass-dialog"
    :close-on-click-modal="false"
    :show-close="!building"
  >
    <div class="build-log-container">
      <div class="build-log-header">
        <div class="build-info">
          <span class="build-image-name">{{ buildForm.image_name }}</span>
          <span class="build-status" :class="buildStatus">{{ buildStatusText }}</span>
        </div>
        <div class="build-progress" v-if="building">
          <el-progress :percentage="buildProgress" :show-text="false" />
        </div>
      </div>
      <div class="build-log-content" ref="buildLogRef">
        <pre class="build-log-text">{{ buildLog }}</pre>
      </div>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="buildLogVisible = false" class="glass-button" :disabled="building">
          <i class="fa fa-times"></i>
          关闭
        </el-button>
        <el-button @click="clearBuildLog" class="glass-button" :disabled="building">
          <i class="fa fa-trash"></i>
          清空日志
        </el-button>
      </div>
    </template>
  </el-dialog>

  <!-- 推送进度对话框 -->
  <el-dialog
    v-model="pushProgressVisible"
    title="推送镜像进度"
    width="500px"
    class="glass-dialog"
    :close-on-click-modal="false"
    :show-close="false"
  >
    <div class="progress-content">
      <div class="progress-info">
        <h4>正在推送镜像</h4>
        <p class="image-name">{{ pushImageName }}</p>
      </div>

      <div class="progress-bar-container">
        <el-progress
          :percentage="Math.round(pushProgress)"
          :stroke-width="8"
          :color="pushProgress === 100 ? '#67C23A' : '#409EFF'"
        />
        <div class="progress-status">{{ pushStatus }}</div>
      </div>
    </div>
  </el-dialog>

  <!-- 拉取镜像对话框 -->
  <el-dialog
    v-model="pullDialogVisible"
    title="拉取镜像"
    width="600px"
    class="glass-dialog"
    :close-on-click-modal="false"
    :destroy-on-close="true"
  >
    <div class="dialog-form-glass">
      <el-form :model="pullForm" label-width="120px" class="form-glass">
        <el-form-item label="镜像仓库" required>
          <el-select v-model="pullForm.registry_type" class="glass-select" style="width: 100%">
            <el-option label="Docker Hub (官方)" value="dockerhub">
              <div class="registry-option">
                <i class="fa fa-docker"></i>
                <span>Docker Hub (docker.io)</span>
              </div>
            </el-option>
            <el-option label="Harbor (私有)" value="harbor">
              <div class="registry-option">
                <i class="fa fa-ship"></i>
                <span>Harbor (私有仓库)</span>
              </div>
            </el-option>
          </el-select>
          <div class="form-tip">选择要从哪个镜像仓库拉取镜像</div>
        </el-form-item>
        <el-form-item label="Harbor仓库" v-if="pullForm.registry_type === 'harbor'" required>
          <el-select
            v-model="pullForm.selected_harbor"
            class="glass-select"
            style="width: 100%"
            placeholder="请选择Harbor仓库"
            @change="loadHarborProjectsForPull"
          >
            <el-option
              v-for="harbor in harborRegistries"
              :key="harbor.id"
              :label="harbor.name"
              :value="harbor.id"
            >
              <div class="registry-option">
                <i class="fa fa-ship"></i>
                <span>{{ harbor.name }} ({{ harbor.url }})</span>
              </div>
            </el-option>
            <el-option v-if="harborRegistries.length === 0" label="暂无Harbor仓库" value="" disabled>
              <div class="registry-option">
                <i class="fa fa-info-circle"></i>
                <span>请先在镜像仓库管理中添加Harbor仓库</span>
              </div>
            </el-option>
          </el-select>
          <div class="form-tip">选择要使用的Harbor私有仓库（需要先在镜像仓库管理中配置）</div>
        </el-form-item>

        <el-form-item label="Harbor项目" v-if="pullForm.registry_type === 'harbor' && pullForm.selected_harbor" required>
          <el-select
            v-model="pullForm.harbor_project"
            class="glass-select"
            style="width: 100%"
            placeholder="请选择Harbor项目"
            @change="loadHarborImagesForPull"
          >
            <el-option
              v-for="project in pullHarborProjects"
              :key="project.name"
              :label="project.name"
              :value="project.name"
            >
              <div class="project-option">
                <i class="fa fa-folder"></i>
                <span>{{ project.name }}</span>
                <span class="project-access">{{ project.public ? '公开' : '私有' }}</span>
              </div>
            </el-option>
          </el-select>
          <div class="form-tip">选择Harbor项目</div>
        </el-form-item>
        <el-form-item label="镜像名称" required>
          <el-select
            v-if="pullForm.registry_type === 'harbor' && pullForm.harbor_project"
            v-model="pullForm.image_name"
            class="glass-select"
            style="width: 100%"
            placeholder="请选择镜像"
            filterable
          >
            <el-option
              v-for="image in pullHarborImages"
              :key="image.name"
              :label="image.name"
              :value="image.name"
            >
              <div class="image-option">
                <span class="image-name">{{ image.name }}</span>
                <span class="image-count">{{ image.artifact_count }} 个版本</span>
              </div>
            </el-option>
            <el-option v-if="pullHarborImages.length === 0" label="该项目暂无镜像" value="" disabled>
              <div class="image-option">
                <i class="fa fa-info-circle"></i>
                <span>该项目下暂无可拉取的镜像</span>
              </div>
            </el-option>
          </el-select>
          <el-input
            v-else
            v-model="pullForm.image_name"
            placeholder="例如: nginx, mysql, redis"
            class="glass-input"
          />
          <div class="form-tip" v-if="pullForm.registry_type === 'harbor'">从Harbor项目中选择要拉取的镜像</div>
          <div class="form-tip" v-else>镜像的名称，不包含标签</div>
        </el-form-item>
        <el-form-item label="镜像标签">
          <el-select
            v-if="pullForm.registry_type === 'harbor' && pullForm.image_name"
            v-model="pullForm.tag"
            class="glass-select"
            style="width: 100%"
            placeholder="请选择标签"
            filterable
          >
            <el-option
              v-for="tag in pullHarborTags"
              :key="tag.name"
              :label="tag.name"
              :value="tag.name"
            >
              <div class="tag-option">
                <span class="tag-name">{{ tag.name }}</span>
                <span class="tag-size">{{ formatSize(tag.size) }}</span>
              </div>
            </el-option>
            <el-option v-if="pullHarborTags.length === 0" label="该镜像暂无标签" value="" disabled>
              <div class="tag-option">
                <i class="fa fa-info-circle"></i>
                <span>该镜像下暂无可用标签</span>
              </div>
            </el-option>
          </el-select>
          <el-input
            v-else
            v-model="pullForm.tag"
            placeholder="例如: latest, 1.20, alpine"
            class="glass-input"
          />
          <div class="form-tip" v-if="pullForm.registry_type === 'harbor'">从Harbor镜像中选择要拉取的标签版本</div>
          <div class="form-tip" v-else>镜像的版本标签，默认为 latest</div>
        </el-form-item>
        <div class="pull-preview">
          <div class="preview-label">
            <i class="fa fa-eye"></i>
            完整镜像名称预览：
          </div>
          <div class="preview-content">
            <code>
              {{ getImagePreview() }}
            </code>
          </div>
        </div>
      </el-form>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="pullDialogVisible = false" class="glass-button">
          <i class="fa fa-times"></i>
          取消
        </el-button>
        <el-button @click="submitPullImage" class="glass-button add-button">
          <i class="fa fa-download"></i>
          开始拉取
        </el-button>
      </div>
    </template>
  </el-dialog>

  <!-- 运行容器对话框 -->
  <el-dialog
    v-model="runDialogVisible"
    title="运行容器"
    width="900px"
    class="glass-dialog"
    :close-on-click-modal="false"
    :destroy-on-close="true"
  >
    <div class="dialog-form-glass">
      <el-tabs v-model="activeTab" class="run-container-tabs">
        <!-- 基本配置 -->
        <el-tab-pane label="基本配置" name="basic">
          <el-form :model="runForm" label-width="140px" class="form-glass">
            <el-form-item label="容器名称">
              <el-input
                v-model="runForm.container_name"
                placeholder="可选，留空则自动生成"
                class="glass-input"
              />
              <div class="form-tip">为容器指定一个名称，便于管理</div>
            </el-form-item>

            <el-form-item label="重启策略">
              <el-select v-model="runForm.restart_policy" class="glass-select" style="width: 100%">
                <el-option label="不重启 (no)" value="no" />
                <el-option label="总是重启 (always)" value="always" />
                <el-option label="除非手动停止 (unless-stopped)" value="unless-stopped" />
                <el-option label="失败时重启 (on-failure)" value="on-failure" />
              </el-select>
              <div class="form-tip">容器退出时的重启策略</div>
            </el-form-item>

            <el-form-item label="运行选项">
              <div class="run-options">
                <el-checkbox v-model="runForm.auto_remove" class="run-option-checkbox">
                  <span class="option-label">自动删除 (--rm)</span>
                  <div class="option-desc">容器停止后自动删除</div>
                </el-checkbox>
                <el-checkbox v-model="runForm.privileged" class="run-option-checkbox">
                  <span class="option-label">特权模式 (--privileged)</span>
                  <div class="option-desc">给予容器扩展权限</div>
                </el-checkbox>
              </div>
            </el-form-item>

            <el-form-item label="运行用户">
              <el-input
                v-model="runForm.user"
                placeholder="例如: 1000:1000 或 root"
                class="glass-input"
              />
              <div class="form-tip">指定容器内运行进程的用户，格式：用户ID:组ID</div>
            </el-form-item>

            <el-form-item label="工作目录">
              <el-input
                v-model="runForm.working_dir"
                placeholder="例如: /app"
                class="glass-input"
              />
              <div class="form-tip">设置容器内的工作目录</div>
            </el-form-item>

            <el-form-item label="主机名">
              <el-input
                v-model="runForm.hostname"
                placeholder="例如: my-container"
                class="glass-input"
              />
              <div class="form-tip">设置容器的主机名</div>
            </el-form-item>
          </el-form>
        </el-tab-pane>

        <!-- 网络与端口 -->
        <el-tab-pane label="网络与端口" name="network">
          <el-form :model="runForm" label-width="140px" class="form-glass">
            <el-form-item label="网络模式">
              <el-select v-model="runForm.network_mode" class="glass-select" style="width: 100%" @focus="loadNetworksForSelect">
                <el-option label="默认网络 (default)" value="default" />
                <el-option
                  v-for="network in availableNetworks"
                  :key="network.Id"
                  :label="`${network.Name} (${network.Driver})`"
                  :value="network.Name"
                />
              </el-select>
              <div class="form-tip">选择容器的网络模式</div>
            </el-form-item>

            <el-form-item label="端口映射">
              <el-input
                v-model="runForm.ports"
                type="textarea"
                :rows="4"
                placeholder="每行一个端口映射，例如:&#10;8080:80&#10;3306:3306&#10;443:443"
                class="glass-input"
              />
              <div class="form-tip">将主机端口映射到容器端口，格式：主机端口:容器端口</div>
            </el-form-item>
          </el-form>
        </el-tab-pane>

        <!-- 存储与挂载 -->
        <el-tab-pane label="存储与挂载" name="storage">
          <el-form :model="runForm" label-width="140px" class="form-glass">
            <el-form-item label="数据卷挂载">
              <el-input
                v-model="runForm.volumes"
                type="textarea"
                :rows="4"
                placeholder="每行一个挂载，例如:&#10;/host/data:/container/data&#10;/host/logs:/var/log&#10;/host/config:/etc/config:ro"
                class="glass-input"
              />
              <div class="form-tip">将主机目录挂载到容器内，格式：主机路径:容器路径[:权限]</div>
            </el-form-item>
          </el-form>
        </el-tab-pane>

        <!-- 环境变量 -->
        <el-tab-pane label="环境变量" name="environment">
          <el-form :model="runForm" label-width="140px" class="form-glass">
            <el-form-item label="环境变量">
              <div class="env-vars-container">
                <div
                  v-for="(envVar, index) in runForm.env_vars"
                  :key="index"
                  class="env-var-item"
                >
                  <el-input
                    v-model="envVar.key"
                    placeholder="变量名，例如: MYSQL_ROOT_PASSWORD"
                    class="glass-input env-key-input"
                  />
                  <span class="env-separator">=</span>
                  <el-input
                    v-model="envVar.value"
                    placeholder="变量值，例如: 123456"
                    class="glass-input env-value-input"
                  />
                  <el-button
                    @click="removeRunEnvVar(index)"
                    class="glass-button delete-button env-remove-btn"
                    size="small"
                    :disabled="runForm.env_vars.length === 1"
                  >
                    <i class="fa fa-minus"></i>
                  </el-button>
                </div>
                <el-button
                  @click="addRunEnvVar"
                  class="glass-button add-button env-add-btn"
                  size="small"
                >
                  <i class="fa fa-plus"></i>
                  添加环境变量
                </el-button>
              </div>
              <div class="form-tip">设置容器的环境变量，格式：变量名=变量值</div>
            </el-form-item>
          </el-form>
        </el-tab-pane>

        <!-- 命令与资源 -->
        <el-tab-pane label="命令与资源" name="command">
          <el-form :model="runForm" label-width="140px" class="form-glass">
            <el-form-item label="启动命令">
              <el-input
                v-model="runForm.command"
                placeholder="例如: /bin/bash"
                class="glass-input"
              />
              <div class="form-tip">覆盖镜像的默认启动命令（可选）</div>
            </el-form-item>

            <el-form-item label="命令参数">
              <el-input
                v-model="runForm.args"
                placeholder="例如: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci"
                class="glass-input"
              />
              <div class="form-tip">传递给镜像的参数，多个参数用空格分隔</div>
            </el-form-item>

            <el-form-item label="内存限制">
              <el-input
                v-model="runForm.memory_limit"
                placeholder="例如: 512m, 1g"
                class="glass-input"
              />
              <div class="form-tip">限制容器使用的内存大小</div>
            </el-form-item>

            <el-form-item label="CPU限制">
              <el-input
                v-model="runForm.cpu_limit"
                placeholder="例如: 0.5, 1.0, 2"
                class="glass-input"
              />
              <div class="form-tip">限制容器使用的CPU核心数</div>
            </el-form-item>
          </el-form>
        </el-tab-pane>
      </el-tabs>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="runDialogVisible = false" class="glass-button">
          <i class="fa fa-times"></i>
          取消
        </el-button>
        <el-button @click="submitRunContainer" class="glass-button add-button">
          <i class="fa fa-play"></i>
          运行容器
        </el-button>
      </div>
    </template>
  </el-dialog>

  <!-- 标签镜像对话框 -->
  <el-dialog
    v-model="tagDialogVisible"
    title="添加镜像标签"
    width="550px"
    class="glass-dialog"
    :close-on-click-modal="false"
    :destroy-on-close="true"
  >
    <div class="dialog-form-glass">
      <el-form :model="tagForm" label-width="120px" class="form-glass">
        <el-form-item label="当前镜像" v-if="currentImage">
          <div class="current-image">
            <i class="fa fa-layer-group"></i>
            {{ currentImage.repository }}:{{ currentImage.tag }}
          </div>
        </el-form-item>
        <el-form-item label="新标签" required>
          <el-input
            v-model="tagForm.target_image"
            placeholder="例如: myapp:v1.0"
            class="glass-input"
          />
          <div class="form-tip">新的镜像名称和标签，格式：name:tag</div>
        </el-form-item>
      </el-form>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="tagDialogVisible = false" class="glass-button">
          <i class="fa fa-times"></i>
          取消
        </el-button>
        <el-button @click="submitTagImage" class="glass-button sync-button">
          <i class="fa fa-tag"></i>
          添加标签
        </el-button>
      </div>
    </template>
  </el-dialog>

  <!-- 导出镜像对话框 -->
  <el-dialog
    v-model="exportDialogVisible"
    title="导出镜像"
    width="600px"
    class="glass-dialog"
    :close-on-click-modal="false"
    :destroy-on-close="true"
  >
    <div class="dialog-form-glass">
      <el-form :model="exportForm" label-width="120px" class="form-glass">
        <el-form-item label="当前镜像" v-if="currentImage">
          <div class="current-image">
            <i class="fa fa-layer-group"></i>
            {{ currentImage.repository }}:{{ currentImage.tag }}
          </div>
        </el-form-item>
        <el-form-item label="导出方式" required>
          <el-radio-group v-model="exportForm.export_type" class="export-type-group">
            <el-radio label="server" class="export-radio">
              <div class="export-option">
                <i class="fa fa-server"></i>
                <div class="export-option-content">
                  <div class="export-option-title">导出到服务器</div>
                  <div class="export-option-desc">将镜像导出为tar文件保存在服务器指定目录</div>
                </div>
              </div>
            </el-radio>
            <el-radio label="download" class="export-radio">
              <div class="export-option">
                <i class="fa fa-download"></i>
                <div class="export-option-content">
                  <div class="export-option-title">下载到本地</div>
                  <div class="export-option-desc">将镜像导出并下载到本地计算机</div>
                </div>
              </div>
            </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="导出路径" v-if="exportForm.export_type === 'server'" required>
          <el-input
            v-model="exportForm.output_file"
            placeholder="例如: /tmp/myimage.tar"
            class="glass-input"
          />
          <div class="form-tip">镜像将被导出到服务器上的此路径</div>
        </el-form-item>
      </el-form>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="exportDialogVisible = false" class="glass-button">
          <i class="fa fa-times"></i>
          取消
        </el-button>
        <el-button @click="submitExportImage" class="glass-button import-button">
          <i class="fa fa-upload" v-if="exportForm.export_type === 'server'"></i>
          <i class="fa fa-download" v-else></i>
          {{ exportForm.export_type === 'server' ? '导出到服务器' : '下载到本地' }}
        </el-button>
      </div>
    </template>
  </el-dialog>

  <!-- 拉取镜像进度对话框 -->
  <el-dialog
    v-model="pullProgressVisible"
    title="拉取镜像"
    width="500px"
    class="glass-dialog"
    :close-on-click-modal="false"
    :show-close="false"
  >
    <div class="pull-progress-container">
      <div class="pull-image-info">
        <i class="fa fa-download pull-icon"></i>
        <div class="pull-image-name">{{ pullImageName }}</div>
      </div>

      <div class="pull-progress-wrapper">
        <el-progress
          :percentage="Math.floor(pullProgress)"
          :stroke-width="8"
          color="#a4f4ba"
          class="pull-progress-bar"
          :show-text="true"
          :format="(percentage) => `${Math.floor(percentage)}%`"
        />
        <div class="pull-status">{{ pullStatus }}</div>
      </div>

      <div class="pull-tips">
        <i class="fa fa-info-circle"></i>
        <span>请耐心等待，镜像拉取时间取决于镜像大小和网络速度</span>
      </div>
    </div>
  </el-dialog>

  <!-- 导出镜像进度对话框 -->
  <el-dialog
    v-model="exportProgressVisible"
    title="导出镜像"
    width="500px"
    class="glass-dialog"
    :close-on-click-modal="false"
    :show-close="false"
  >
    <div class="export-progress-container">
      <div class="export-image-info">
        <i class="fa fa-upload export-icon"></i>
        <div class="export-image-name">{{ exportImageName }}</div>
      </div>

      <div class="export-progress-wrapper">
        <el-progress
          :percentage="Math.floor(exportProgress)"
          :stroke-width="8"
          color="#a4f4ba"
          class="export-progress-bar"
        />
        <div class="export-progress-text">{{ exportStatus }}</div>
      </div>

      <div class="export-tips">
        <i class="fa fa-info-circle"></i>
        <span>正在导出镜像到服务器，请耐心等待...</span>
      </div>
    </div>
  </el-dialog>

  <!-- 镜像详情对话框 -->
  <el-dialog
    v-model="inspectDialogVisible"
    :title="inspectDialogTitle"
    width="90%"
    top="5vh"
    class="glass-dialog inspect-dialog"
    destroy-on-close
  >
    <template #header="{ titleId, titleClass }">
      <div class="inspect-header">
        <div class="inspect-title">
          <i class="fa fa-info-circle inspect-icon"></i>
          <span :id="titleId" :class="titleClass">{{ inspectDialogTitle }}</span>
        </div>
        <div class="inspect-controls">
          <el-button @click="refreshInspect" size="small" class="glass-button">
            <i class="fa fa-refresh"></i>
            刷新
          </el-button>
          <el-button @click="copyInspectContent" class="glass-button">
            <i class="fa fa-copy"></i>
            复制
          </el-button>
          <el-button @click="scrollInspectToTop" class="glass-button">
            <i class="fa fa-arrow-up"></i>
            顶部
          </el-button>
          <el-button @click="scrollInspectToBottom" class="glass-button">
            <i class="fa fa-arrow-down"></i>
            底部
          </el-button>
          <el-button @click="closeInspectDialog" class="glass-button danger">
            <i class="fa fa-times"></i>
            关闭
          </el-button>
        </div>
      </div>
    </template>
    <div class="inspect-content" ref="inspectContentRef">
      <pre class="inspect-pre">{{ inspectContent }}</pre>
    </div>
  </el-dialog>

  <!-- 推送镜像对话框 -->
  <el-dialog
    v-model="pushDialogVisible"
    title="推送镜像到Harbor"
    width="600px"
    class="glass-dialog"
    :close-on-click-modal="false"
    :destroy-on-close="true"
  >
    <div class="dialog-form-glass">
      <!-- 推送说明 -->
      <div class="push-info">
        <div class="info-item">
          <i class="fa fa-info-circle"></i>
          <span>将使用Harbor仓库配置中的认证信息进行推送</span>
        </div>
      </div>

      <el-form :model="pushForm" label-width="120px" class="form-glass">
        <el-form-item label="选择镜像" required>
          <el-select v-model="pushForm.selected_image" placeholder="选择要推送的镜像" class="glass-select" style="width: 100%">
            <el-option
              v-for="image in images"
              :key="image.id"
              :label="`${image.repository}:${image.tag}`"
              :value="image.id"
            >
              <div class="image-option">
                <span class="image-name">{{ image.repository }}:{{ image.tag }}</span>
                <span class="image-size">{{ image.size }}</span>
                <span v-if="image.repository.includes('/')" class="image-tag-badge">已标记</span>
              </div>
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="Harbor仓库" required>
          <el-select
            v-model="pushForm.harbor_registry"
            placeholder="选择Harbor仓库"
            class="glass-select"
            style="width: 100%"
            @change="loadHarborProjects"
          >
            <el-option
              v-for="registry in harborRegistries"
              :key="registry.id"
              :label="registry.name"
              :value="registry.id"
            >
              <div class="registry-option">
                <i class="fa fa-ship"></i>
                <span>{{ registry.name }}</span>
                <span class="registry-url">({{ registry.url }})</span>
              </div>
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="Harbor项目" required v-if="pushForm.harbor_registry">
          <el-select v-model="pushForm.harbor_project" placeholder="选择Harbor项目" class="glass-select" style="width: 100%">
            <el-option
              v-for="project in harborProjects"
              :key="project.name"
              :label="project.name"
              :value="project.name"
            >
              <div class="project-option">
                <i class="fa fa-folder"></i>
                <span>{{ project.name }}</span>
                <span class="project-access">{{ project.public ? '公开' : '私有' }}</span>
              </div>
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="镜像标签" required>
          <el-input v-model="pushForm.tag" placeholder="例如: latest, v1.0.0" class="glass-input" />
        </el-form-item>

        <!-- 预览推送信息 -->
        <div class="push-preview" v-if="pushForm.selected_image && pushForm.harbor_registry && pushForm.harbor_project">
          <h4>推送预览</h4>
          <div class="preview-info">
            <div class="preview-item">
              <span class="label">源镜像:</span>
              <code>{{ getSelectedImageName() }}</code>
            </div>
            <div class="preview-item">
              <span class="label">目标镜像:</span>
              <code>{{ getTargetImageName() }}</code>
            </div>
            <div class="preview-commands">
              <span class="label">执行命令:</span>
              <div class="command-line">
                <code>docker tag {{ getSelectedImageName() }} {{ getTargetImageName() }}</code>
              </div>
              <div class="command-line">
                <code>docker push {{ getTargetImageName() }}</code>
              </div>
            </div>
          </div>
        </div>
      </el-form>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="pushDialogVisible = false" class="glass-button">
          <i class="fa fa-times"></i>
          取消
        </el-button>
        <el-button
          @click="submitPushImage"
          class="glass-button upload-button"
        >
          <i class="fa fa-upload"></i>
          开始推送
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { dockerImageAPI, dockerRegistryAPI, dockerServerAPI } from '@/api/docker'
import { ElMessage, ElMessageBox } from 'element-plus'
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'

// 响应式数据
const loading = ref(false)
const selectedServer = ref('')

// 统计数据
const statistics = reactive({
  total_images: 0,
  total_size: '0 MB',
  dangling_images: 0
})

// 数据列表
const dockerServers = ref([])
const images = ref([])

// 对话框状态
const buildDialogVisible = ref(false)
const runDialogVisible = ref(false)
const pullDialogVisible = ref(false)
const pushDialogVisible = ref(false)
const pushProgressVisible = ref(false)
const tagDialogVisible = ref(false)
const exportDialogVisible = ref(false)
const inspectDialogVisible = ref(false)
const pullProgressVisible = ref(false)

// 网络列表
const availableNetworks = ref([])

// 拉取进度相关
const pullProgress = ref(0)
const pullStatus = ref('')
const pullImageName = ref('')

// 推送进度相关
const pushProgress = ref(0)
const pushStatus = ref('')
const pushImageName = ref('')

// 导出进度相关
const exportProgressVisible = ref(false)
const exportProgress = ref(0)
const exportStatus = ref('')
const exportImageName = ref('')

// inspect相关变量
const inspectDialogTitle = ref('')
const inspectContent = ref('')
const inspectContentRef = ref()
const currentInspectImage = ref(null)

// 运行容器标签页
const activeTab = ref('basic')

// 当前操作的镜像
const currentImage = ref(null)

// 构建镜像表单
const buildForm = reactive({
  base_image: 'nginx:alpine',
  image_name: '',
  maintainer: '',
  work_dir: '/app',
  copy_files: [{ source: '', target: '' }],
  add_files: [{ source: '', target: '' }],
  run_commands: [''],
  env_vars: [{ key: '', value: '' }],
  labels: [{ key: '', value: '' }],
  volumes: [''],
  expose_ports: [],
  cmd_command: '',
  entrypoint_command: '',
  new_port: ''
})

// 上传的文件
const uploadedFiles = ref(new Map())

// 构建日志相关变量
const buildLogVisible = ref(false)
const buildLog = ref('')
const building = ref(false)
const buildStatus = ref('ready') // ready, building, success, failed
const buildProgress = ref(0)
const buildLogRef = ref(null)

// 预设的基础镜像选项
const baseImageOptions = [
  'nginx:alpine',
  'python:3.9',
  'python:3.10',
  'python:3.11',
  'node:16',
  'node:18',
  'node:20',
  'ubuntu:20.04',
  'ubuntu:22.04',
  'alpine:latest',
  'centos:7',
  'redis:alpine',
  'mysql:8.0'
]

// 构建状态文本
const buildStatusText = computed(() => {
  switch (buildStatus.value) {
    case 'ready': return '准备就绪'
    case 'building': return '构建中...'
    case 'success': return '构建成功'
    case 'failed': return '构建失败'
    default: return '未知状态'
  }
})

// 生成的Dockerfile内容
const generatedDockerfile = computed(() => {
  try {
    let dockerfile = `FROM ${buildForm.base_image || 'nginx:alpine'}\n`

    // MAINTAINER (已废弃，但仍支持)
    if (buildForm.maintainer && buildForm.maintainer.trim()) {
      dockerfile += `MAINTAINER ${buildForm.maintainer}\n`
    }

    // LABEL指令
    if (buildForm.labels && Array.isArray(buildForm.labels)) {
      buildForm.labels.forEach(label => {
        if (label && label.key && label.value) {
          dockerfile += `LABEL ${label.key}="${label.value}"\n`
        }
      })
    }

    // ENV指令
    if (buildForm.env_vars && Array.isArray(buildForm.env_vars)) {
      buildForm.env_vars.forEach(env => {
        if (env && env.key && env.value) {
          dockerfile += `ENV ${env.key}=${env.value}\n`
        }
      })
    }

    // WORKDIR指令
    if (buildForm.work_dir && buildForm.work_dir.trim()) {
      dockerfile += `WORKDIR ${buildForm.work_dir}\n`
    }

    // COPY指令
    if (buildForm.copy_files && Array.isArray(buildForm.copy_files)) {
      buildForm.copy_files.forEach(file => {
        if (file && file.source && file.target) {
          dockerfile += `COPY ${file.source} ${file.target}\n`
        }
      })
    }

    // ADD指令
    if (buildForm.add_files && Array.isArray(buildForm.add_files)) {
      buildForm.add_files.forEach(file => {
        if (file && file.source && file.target) {
          dockerfile += `ADD ${file.source} ${file.target}\n`
        }
      })
    }

    // RUN指令
    if (buildForm.run_commands && Array.isArray(buildForm.run_commands)) {
      buildForm.run_commands.forEach(cmd => {
        if (cmd && cmd.trim()) {
          dockerfile += `RUN ${cmd}\n`
        }
      })
    }

    // VOLUME指令
    if (buildForm.volumes && Array.isArray(buildForm.volumes)) {
      buildForm.volumes.forEach(volume => {
        if (volume && volume.trim()) {
          dockerfile += `VOLUME ["${volume}"]\n`
        }
      })
    }

    // EXPOSE指令
    if (buildForm.expose_ports && buildForm.expose_ports.length > 0) {
      dockerfile += `EXPOSE ${buildForm.expose_ports.join(' ')}\n`
    }

    // ENTRYPOINT指令
    if (buildForm.entrypoint_command && buildForm.entrypoint_command.trim()) {
      const cmd = buildForm.entrypoint_command.trim()
      // 如果用户输入的命令已经是JSON数组格式，直接使用
      if (cmd.startsWith('[') && cmd.endsWith(']')) {
        dockerfile += `ENTRYPOINT ${cmd}\n`
      } else {
        // 智能解析：正确处理引号内的内容
        const args = []
        let current = ''
        let inQuotes = false
        let quoteChar = ''

        for (let i = 0; i < cmd.length; i++) {
          const char = cmd[i]

          if ((char === '"' || char === "'") && !inQuotes) {
            // 开始引号
            inQuotes = true
            quoteChar = char
            // 不包含引号字符本身
          } else if (char === quoteChar && inQuotes) {
            // 结束引号
            inQuotes = false
            quoteChar = ''
            // 不包含引号字符本身
          } else if (char === ' ' && !inQuotes) {
            // 空格且不在引号内，分割参数
            if (current.trim()) {
              args.push(current.trim())
              current = ''
            }
          } else {
            // 普通字符或引号内的字符
            current += char
          }
        }

        // 添加最后一个参数
        if (current.trim()) {
          args.push(current.trim())
        }

        if (args.length > 0) {
          dockerfile += `ENTRYPOINT [${args.map(arg => `"${arg}"`).join(', ')}]\n`
        }
      }
    }

    // CMD指令
    if (buildForm.cmd_command && buildForm.cmd_command.trim()) {
      const cmd = buildForm.cmd_command.trim()
      // 如果用户输入的命令已经是JSON数组格式，直接使用
      if (cmd.startsWith('[') && cmd.endsWith(']')) {
        dockerfile += `CMD ${cmd}\n`
      } else {
        // 智能解析：正确处理引号内的内容
        const args = []
        let current = ''
        let inQuotes = false
        let quoteChar = ''

        for (let i = 0; i < cmd.length; i++) {
          const char = cmd[i]

          if ((char === '"' || char === "'") && !inQuotes) {
            // 开始引号
            inQuotes = true
            quoteChar = char
            // 不包含引号字符本身
          } else if (char === quoteChar && inQuotes) {
            // 结束引号
            inQuotes = false
            quoteChar = ''
            // 不包含引号字符本身
          } else if (char === ' ' && !inQuotes) {
            // 空格且不在引号内，分割参数
            if (current.trim()) {
              args.push(current.trim())
              current = ''
            }
          } else {
            // 普通字符或引号内的字符
            current += char
          }
        }

        // 添加最后一个参数
        if (current.trim()) {
          args.push(current.trim())
        }

        if (args.length > 0) {
          dockerfile += `CMD [${args.map(arg => `"${arg}"`).join(', ')}]\n`
        }
      }
    }

    return dockerfile
  } catch (error) {
    console.error('生成Dockerfile失败:', error)
    return 'FROM nginx:alpine\n'
  }
})

// 运行容器表单
const runForm = reactive({
  container_name: '',
  ports: '',
  volumes: '',
  env_vars: [{ key: '', value: '' }],
  command: '',
  args: '',
  restart_policy: 'no', // no, always, unless-stopped, on-failure
  auto_remove: false, // --rm
  privileged: false, // --privileged
  user: '', // --user
  working_dir: '', // --workdir
  hostname: '', // --hostname
  network_mode: 'default', // --network
  memory_limit: '', // --memory
  cpu_limit: '' // --cpus
})

// 拉取镜像表单
const pullForm = reactive({
  registry_type: 'dockerhub',
  image_name: '',
  tag: 'latest',
  selected_harbor: '',
  harbor_project: ''
})

// Harbor仓库列表
const harborRegistries = ref([])

// 推送镜像表单
const pushForm = reactive({
  selected_image: '',
  harbor_registry: '',
  harbor_project: '',
  tag: 'latest'
})

// Harbor相关数据
const harborProjects = ref([])
const pullHarborProjects = ref([])
const pullHarborImages = ref([])
const pullHarborTags = ref([])

// 标签镜像表单
const tagForm = reactive({
  target_image: ''
})

// 导出镜像表单
const exportForm = reactive({
  export_type: 'server', // server: 导出到服务器, download: 下载到本地
  output_file: ''
})

// 监听服务器选择变化
watch(selectedServer, (newValue, oldValue) => {
  if (newValue !== oldValue) {
    // 立即清空之前的数据
    images.value = []
    Object.assign(statistics, {
      total_images: 0,
      total_size: '0 MB',
      dangling_images: 0
    })

    if (newValue) {
      loadImages().then(() => {
        loadStatistics()
      })
    }
  }
})

// 监听Harbor项目选择变化，加载镜像列表
watch(() => pullForm.harbor_project, (newValue) => {
  if (newValue && pullForm.registry_type === 'harbor') {
    loadHarborImagesForPull()
  } else {
    pullHarborImages.value = []
    pullHarborTags.value = []
    pullForm.image_name = ''
    pullForm.tag = 'latest'
  }
})

// 监听Harbor镜像选择变化，加载标签列表
watch(() => pullForm.image_name, (newValue) => {
  if (newValue && pullForm.registry_type === 'harbor') {
    loadHarborTagsForPull()
  } else {
    pullHarborTags.value = []
    if (pullForm.registry_type === 'harbor') {
      pullForm.tag = ''
    }
  }
})

// 页面加载
onMounted(() => {
  loadData()
})

// 加载Harbor仓库列表
const loadHarborRegistries = async () => {
  try {
    console.log('🔄 开始加载Harbor仓库列表...')
    const response = await dockerRegistryAPI.getRegistries()
    console.log('📦 Harbor仓库API响应:', response)
    const allRegistries = response.data.results || response.data || []
    console.log('📋 所有仓库:', allRegistries)
    harborRegistries.value = allRegistries.filter((registry: any) =>
      registry.registry_type === 'harbor' && registry.is_active
    )
    console.log('✅ Harbor仓库列表:', harborRegistries.value)
  } catch (error) {
    console.error('❌ 加载Harbor仓库失败:', error)
  }
}

// 加载数据
const loadData = async () => {
  loading.value = true
  try {
    await Promise.all([
      loadDockerServers(),
      loadHarborRegistries()
    ])
    if (selectedServer.value) {
      await loadImages()
      await loadStatistics()
    }
  } catch (error) {
    console.error('加载数据失败:', error)
    ElMessage.error('加载数据失败')
  } finally {
    loading.value = false
  }
}

// 加载Docker服务器列表
const loadDockerServers = async () => {
  try {
    const response = await dockerServerAPI.getServers()
    dockerServers.value = response.data.results || response.data || []

    // 如果有服务器且没有选中的服务器，默认选择第一个
    if (dockerServers.value.length > 0 && !selectedServer.value) {
      selectedServer.value = dockerServers.value[0].id
    }
  } catch (error) {
    console.error('加载Docker服务器失败:', error)
    ElMessage.error('加载Docker服务器失败')
  }
}

// 加载镜像列表
const loadImages = async () => {
  if (!selectedServer.value) {
    images.value = []
    // 清空统计数据
    Object.assign(statistics, {
      total_images: 0,
      total_size: '0 MB',
      dangling_images: 0
    })
    return
  }

  try {
    const response = await dockerImageAPI.getImages(selectedServer.value)
    if (response.data.success) {
      images.value = response.data.images || []
    } else {
      ElMessage.error(response.data.message || '加载镜像列表失败')
      images.value = []
      // 清空统计数据
      Object.assign(statistics, {
        total_images: 0,
        total_size: '0 MB',
        dangling_images: 0
      })
    }
  } catch (error) {
    console.error('加载镜像列表失败:', error)
    ElMessage.error('加载镜像列表失败')
    images.value = []
    // 清空统计数据
    Object.assign(statistics, {
      total_images: 0,
      total_size: '0 MB',
      dangling_images: 0
    })
  }
}

// 加载统计数据
const loadStatistics = async () => {
  if (!selectedServer.value) {
    Object.assign(statistics, {
      total_images: 0,
      total_size: '0 MB',
      dangling_images: 0
    })
    return
  }

  try {
    // 计算统计数据
    const totalImages = images.value.length
    console.log(`[统计数据] 服务器${selectedServer.value}: 镜像数量=${totalImages}`)

    // 计算总大小
    let totalSize = 0
    images.value.forEach(image => {
      // 提取数字部分，例如从 "120MB" 提取 120
      const sizeMatch = String(image.size).match(/(\d+(\.\d+)?)/);
      if (sizeMatch) {
        const size = parseFloat(sizeMatch[0]);
        // 根据单位转换为MB
        if (image.size.includes('GB')) {
          totalSize += size * 1024;
        } else if (image.size.includes('KB')) {
          totalSize += size / 1024;
        } else {
          totalSize += size;
        }
      }
      console.log(`[统计数据] 镜像: ${image.repository}:${image.tag}, 大小: ${image.size}`)
    })

    // 计算悬空镜像数量
    const danglingImages = images.value.filter(image =>
      image.repository === '<none>' || image.tag === '<none>'
    ).length

    const newStatistics = {
      total_images: totalImages,
      total_size: totalSize.toFixed(2) + ' MB',
      dangling_images: danglingImages
    }

    console.log(`[统计数据] 服务器${selectedServer.value}最终统计:`, newStatistics)
    Object.assign(statistics, newStatistics)
  } catch (error) {
    console.error('计算统计数据失败:', error)
    Object.assign(statistics, {
      total_images: images.value.length,
      total_size: '计算失败',
      dangling_images: 0
    })
  }
}

// 刷新镜像列表
const refreshImages = () => {
  loadData()
  ElMessage.success('镜像列表已刷新')
}

// 镜像操作
const pullImage = async () => {
  if (!selectedServer.value) {
    ElMessage.warning('请先选择Docker服务器')
    return
  }

  // 打开拉取镜像对话框
  pullDialogVisible.value = true
}

// 推送镜像
const pushImage = async () => {
  if (!selectedServer.value) {
    ElMessage.warning('请先选择Docker服务器')
    return
  }

  if (images.value.length === 0) {
    ElMessage.warning('当前没有可推送的镜像')
    return
  }

  // 直接打开推送镜像对话框
  pushDialogVisible.value = true
}

// 提交拉取镜像
const submitPullImage = async () => {
  if (!pullForm.image_name) {
    ElMessage.warning('镜像名称不能为空')
    return
  }

  try {
    // 构建完整的镜像名称
    let fullImageName = pullForm.image_name
    if (pullForm.tag && pullForm.tag !== 'latest') {
      fullImageName += `:${pullForm.tag}`
    } else if (!pullForm.image_name.includes(':')) {
      fullImageName += ':latest'
    }

    // 根据仓库类型添加前缀
    if (pullForm.registry_type === 'harbor') {
      if (!pullForm.selected_harbor) {
        ElMessage.warning('请选择Harbor仓库')
        return
      }
      // 根据选择的Harbor仓库获取URL
      const selectedHarbor = harborRegistries.value.find(h => h.id === pullForm.selected_harbor)
      if (selectedHarbor) {
        // 清理Harbor URL，移除协议前缀
        let harborUrl = selectedHarbor.url.replace('https://', '').replace('http://', '')

        // 构建完整的Harbor镜像名称：harbor.example.com/project/image:tag
        // 注意：pullForm.image_name 已经包含了项目前缀，如 "library/centos"
        if (pullForm.image_name.includes('/')) {
          // 如果镜像名称已经包含项目路径，直接使用
          fullImageName = `${harborUrl}/${pullForm.image_name}`
        } else {
          // 如果镜像名称不包含项目路径，添加项目前缀
          fullImageName = `${harborUrl}/${pullForm.harbor_project}/${pullForm.image_name}`
        }

        // 添加标签
        if (pullForm.tag && pullForm.tag !== 'latest') {
          fullImageName += `:${pullForm.tag}`
        } else {
          fullImageName += ':latest'
        }
      } else {
        ElMessage.warning('选择的Harbor仓库不存在')
        return
      }
    }

    // 关闭拉取对话框，显示进度对话框
    pullDialogVisible.value = false
    pullProgressVisible.value = true
    pullImageName.value = fullImageName
    pullProgress.value = 0
    pullStatus.value = '开始拉取镜像...'

    // 模拟进度更新 - 确保进度只增不减
    const progressInterval = setInterval(() => {
      if (pullProgress.value < 90) {
        const increment = Math.random() * 5 + 2 // 2-7的随机增量
        pullProgress.value = Math.min(90, pullProgress.value + increment)

        if (pullProgress.value < 30) {
          pullStatus.value = '正在连接镜像仓库...'
        } else if (pullProgress.value < 60) {
          pullStatus.value = '正在下载镜像层...'
        } else if (pullProgress.value < 90) {
          pullStatus.value = '正在解压镜像...'
        }
      }
    }, 800)

    try {
      // 构建拉取参数
      const pullData = {
        image_name: fullImageName
      }

      // 如果是Harbor镜像，添加Harbor仓库ID
      if (pullForm.registry_type === 'harbor' && pullForm.selected_harbor) {
        pullData.harbor_registry_id = pullForm.selected_harbor
      }

      const response = await dockerImageAPI.pullImageWithData(selectedServer.value, pullData)

      clearInterval(progressInterval)
      pullProgress.value = 100
      pullStatus.value = '镜像拉取完成'

      setTimeout(() => {
        pullProgressVisible.value = false

        if (response.data.success) {
          ElMessage.success('镜像拉取成功')
          resetPullForm()
          loadImages()
          loadStatistics()
        } else {
          ElMessage.error(response.data.message || '拉取镜像失败')
        }
      }, 1000)

    } catch (error) {
      clearInterval(progressInterval)
      pullProgressVisible.value = false
      console.error('拉取镜像失败:', error)
      ElMessage.error('拉取镜像失败')
    }
  } catch (error) {
    console.error('拉取镜像操作失败:', error)
    ElMessage.error('拉取镜像操作失败')
  }
}

// 重置拉取表单
const resetPullForm = () => {
  pullForm.registry_type = 'dockerhub'
  pullForm.image_name = ''
  pullForm.tag = 'latest'
  pullForm.selected_harbor = ''
}

// 获取镜像预览
const getImagePreview = () => {
  const imageName = pullForm.image_name || 'image-name'
  const tag = pullForm.tag || 'latest'

  if (pullForm.registry_type === 'harbor') {
    const selectedHarbor = harborRegistries.value.find(h => h.id === pullForm.selected_harbor)
    if (selectedHarbor) {
      return `${selectedHarbor.url}/${imageName}:${tag}`
    } else {
      return `harbor.example.com/${imageName}:${tag}`
    }
  } else {
    return `${imageName}:${tag}`
  }
}

// 加载Harbor项目列表
const loadHarborProjects = async () => {
  if (!pushForm.harbor_registry) {
    harborProjects.value = []
    return
  }

  try {
    const response = await dockerRegistryAPI.getHarborProjects(pushForm.harbor_registry)
    if (response.data.success) {
      harborProjects.value = response.data.data || []
    }
  } catch (error) {
    console.error('加载Harbor项目失败:', error)
    harborProjects.value = []
  }
}

// 提交推送镜像
const submitPushImage = async () => {
  if (!pushForm.selected_image) {
    ElMessage.warning('请选择要推送的镜像')
    return
  }

  if (!pushForm.harbor_registry) {
    ElMessage.warning('请选择Harbor仓库')
    return
  }

  if (!pushForm.harbor_project) {
    ElMessage.warning('请选择Harbor项目')
    return
  }

  try {
    // 构建Harbor镜像名称
    const selectedImage = images.value.find(img => img.id === pushForm.selected_image)
    if (!selectedImage) {
      ElMessage.error('找不到选中的镜像')
      return
    }

    // 获取Harbor仓库URL
    const harborRegistry = harborRegistries.value.find(r => r.id === pushForm.harbor_registry)
    if (!harborRegistry) {
      ElMessage.error('找不到Harbor仓库配置')
      return
    }

    // 构建符合Harbor命名规则的镜像名称
    const harborUrl = harborRegistry.url.replace(/^https?:\/\//, '')

    // 处理repository名称：如果已经包含Harbor URL，需要提取纯仓库名
    let repositoryName = selectedImage.repository

    // 如果repository包含Harbor URL，提取最后的仓库名部分
    if (repositoryName.includes('/')) {
      const parts = repositoryName.split('/')
      // 取最后一个部分作为仓库名
      repositoryName = parts[parts.length - 1]
    }

    const harborImageName = `${harborUrl}/${pushForm.harbor_project}/${repositoryName}:${pushForm.tag}`

    const pushData = {
      source_image: `${selectedImage.repository}:${selectedImage.tag}`,
      target_image: harborImageName,
      harbor_registry_id: pushForm.harbor_registry
    }

    console.log('🚀 推送数据:', pushData)

    // 关闭推送对话框，显示进度对话框
    pushDialogVisible.value = false
    pushProgressVisible.value = true
    pushImageName.value = harborImageName
    pushProgress.value = 0
    pushStatus.value = '开始推送镜像...'

    // 模拟进度更新
    const progressInterval = setInterval(() => {
      if (pushProgress.value < 90) {
        const increment = Math.random() * 5 + 2 // 2-7的随机增量
        pushProgress.value = Math.min(90, pushProgress.value + increment)

        if (pushProgress.value < 20) {
          pushStatus.value = '正在标记镜像...'
        } else if (pushProgress.value < 40) {
          pushStatus.value = '正在连接Harbor仓库...'
        } else if (pushProgress.value < 70) {
          pushStatus.value = '正在上传镜像层...'
        } else if (pushProgress.value < 90) {
          pushStatus.value = '正在完成推送...'
        }
      }
    }, 800)

    try {
      const response = await dockerRegistryAPI.pushImageToHarbor(selectedServer.value, pushData)

      clearInterval(progressInterval)
      pushProgress.value = 100
      pushStatus.value = '镜像推送完成'

      setTimeout(() => {
        pushProgressVisible.value = false

        if (response.data.success) {
          ElMessage.success('镜像推送成功')
          // 重置表单
          pushForm.selected_image = ''
          pushForm.harbor_project = ''
          pushForm.tag = 'latest'
        } else {
          ElMessage.error(response.data.message || '推送镜像失败')
        }
      }, 1000)

    } catch (error) {
      clearInterval(progressInterval)
      pushProgressVisible.value = false
      console.error('推送镜像失败:', error)
      ElMessage.error('推送镜像失败')
    }
  } catch (error) {
    console.error('推送镜像操作失败:', error)
    ElMessage.error('推送镜像操作失败')
  }
}

// 获取选中镜像名称
const getSelectedImageName = () => {
  const selectedImage = images.value.find(img => img.id === pushForm.selected_image)
  return selectedImage ? `${selectedImage.repository}:${selectedImage.tag}` : ''
}

// 获取目标镜像名称
const getTargetImageName = () => {
  if (!pushForm.harbor_registry || !pushForm.harbor_project) return ''

  const harborRegistry = harborRegistries.value.find(r => r.id === pushForm.harbor_registry)
  if (!harborRegistry) return ''

  const selectedImage = images.value.find(img => img.id === pushForm.selected_image)
  if (!selectedImage) return ''

  const harborUrl = harborRegistry.url.replace(/^https?:\/\//, '')

  // 处理repository名称：如果已经包含Harbor URL，需要提取纯仓库名
  let repositoryName = selectedImage.repository

  // 如果repository包含Harbor URL，提取最后的仓库名部分
  if (repositoryName.includes('/')) {
    const parts = repositoryName.split('/')
    // 取最后一个部分作为仓库名
    repositoryName = parts[parts.length - 1]
  }

  return `${harborUrl}/${pushForm.harbor_project}/${repositoryName}:${pushForm.tag}`
}

// 加载Harbor项目列表（用于拉取镜像）
const loadHarborProjectsForPull = async () => {
  if (!pullForm.selected_harbor) {
    pullHarborProjects.value = []
    return
  }

  try {
    const response = await dockerRegistryAPI.getHarborProjects(pullForm.selected_harbor)
    if (response.data.success) {
      pullHarborProjects.value = response.data.data || []
    }
  } catch (error) {
    console.error('加载Harbor项目失败:', error)
    pullHarborProjects.value = []
  }
}

// 加载Harbor镜像列表（用于拉取镜像）
const loadHarborImagesForPull = async () => {
  if (!pullForm.selected_harbor || !pullForm.harbor_project) {
    pullHarborImages.value = []
    return
  }

  try {
    const response = await dockerRegistryAPI.getHarborRepositories(
      pullForm.selected_harbor,
      pullForm.harbor_project,
      { page: 1, page_size: 100 }
    )
    if (response.data.success) {
      pullHarborImages.value = response.data.data || []
    }
  } catch (error) {
    console.error('加载Harbor镜像失败:', error)
    pullHarborImages.value = []
  }
}

// 加载Harbor镜像标签列表（用于拉取镜像）
const loadHarborTagsForPull = async () => {
  if (!pullForm.selected_harbor || !pullForm.harbor_project || !pullForm.image_name) {
    pullHarborTags.value = []
    return
  }

  try {
    // 处理镜像名称：如果包含项目前缀，需要去掉
    let repositoryName = pullForm.image_name
    if (repositoryName.includes('/')) {
      // 如果镜像名称包含斜杠，取最后一部分作为repository名称
      repositoryName = repositoryName.split('/').pop()
    }

    console.log('🔍 加载Harbor标签:', {
      harbor_id: pullForm.selected_harbor,
      project: pullForm.harbor_project,
      original_image: pullForm.image_name,
      repository_name: repositoryName
    })

    const response = await dockerRegistryAPI.getHarborArtifacts(
      pullForm.selected_harbor,
      pullForm.harbor_project,
      repositoryName,
      { page: 1, page_size: 100 }
    )
    if (response.data.success) {
      // 提取所有标签
      const tags = []
      const artifacts = response.data.data || []

      console.log('📦 Harbor artifacts响应:', artifacts)

      artifacts.forEach(artifact => {
        if (artifact.tags && Array.isArray(artifact.tags)) {
          artifact.tags.forEach(tag => {
            tags.push({
              name: tag.name,
              size: artifact.size || 0,
              push_time: tag.push_time
            })
          })
        }
      })

      console.log('🏷️ 提取的标签列表:', tags)
      pullHarborTags.value = tags

      // 如果当前标签不在列表中，清空选择
      if (pullForm.tag && !tags.find(t => t.name === pullForm.tag)) {
        pullForm.tag = ''
      }
    } else {
      console.error('❌ Harbor artifacts API失败:', response.data)
    }
  } catch (error) {
    console.error('加载Harbor镜像标签失败:', error)
    pullHarborTags.value = []
  }
}

const buildImage = async () => {
  if (!selectedServer.value) {
    ElMessage.warning('请先选择Docker服务器')
    return
  }

  try {
    // 打开构建镜像对话框
    buildDialogVisible.value = true
  } catch (error) {
    console.error('构建镜像操作失败:', error)
    ElMessage.error('构建镜像操作失败')
  }
}

// 提交构建镜像
const submitBuildImage = async () => {
  if (!buildForm.image_name) {
    ElMessage.warning('镜像名称不能为空')
    return
  }

  if (!buildForm.base_image) {
    ElMessage.warning('基础镜像不能为空')
    return
  }

  try {
    // 初始化构建状态
    building.value = true
    buildStatus.value = 'building'
    buildProgress.value = 0
    buildLog.value = ''
    buildLogVisible.value = true

    // 添加初始日志
    appendBuildLog('🚀 开始构建镜像...')
    appendBuildLog(`📦 镜像名称: ${buildForm.image_name}`)
    appendBuildLog(`🐳 基础镜像: ${buildForm.base_image}`)
    appendBuildLog(`🖥️  目标服务器: ${selectedServer.value}`)
    appendBuildLog('')

    buildProgress.value = 10

    // 准备上传的文件数据
    const uploadedFilesData = {}
    if (uploadedFiles.value && uploadedFiles.value.size > 0) {
      console.log('处理上传文件，数量:', uploadedFiles.value.size)
      uploadedFiles.value.forEach((content, filename) => {
        try {
          console.log(`处理文件 ${filename}:`, content instanceof ArrayBuffer ? `ArrayBuffer(${content.byteLength})` : typeof content)

          // 将ArrayBuffer转换为Base64字符串
          if (content instanceof ArrayBuffer) {
            // 使用更可靠的方法转换ArrayBuffer到Base64
            const uint8Array = new Uint8Array(content)
            let binaryString = ''
            const chunkSize = 8192 // 分块处理，避免栈溢出

            for (let i = 0; i < uint8Array.length; i += chunkSize) {
              const chunk = uint8Array.subarray(i, i + chunkSize)
              binaryString += String.fromCharCode.apply(null, chunk)
            }

            uploadedFilesData[filename] = btoa(binaryString)
            console.log(`文件 ${filename} 转换为Base64成功，长度:`, uploadedFilesData[filename].length)
          } else {
            uploadedFilesData[filename] = content
          }
        } catch (error) {
          console.error(`处理文件 ${filename} 失败:`, error)
          ElMessage.error(`处理文件 ${filename} 失败: ${error.message}`)
        }
      })
    } else {
      console.log('没有上传的文件')
    }

    const buildData = {
      dockerfile_content: generatedDockerfile.value,
      image_name: buildForm.image_name,
      uploaded_files: uploadedFilesData
    }

    console.log('构建数据:', buildData)
    console.log('Dockerfile内容:', generatedDockerfile.value)

    appendBuildLog('📝 生成Dockerfile:')
    appendBuildLog('```dockerfile')
    appendBuildLog(generatedDockerfile.value)
    appendBuildLog('```')
    appendBuildLog('')

    buildProgress.value = 30

    try {
      appendBuildLog('🔗 连接到Docker服务器...')
      buildProgress.value = 50

      const response = await dockerImageAPI.buildImage(selectedServer.value, buildData)

      buildProgress.value = 90

      if (response.data.success) {
        buildStatus.value = 'success'
        buildProgress.value = 100
        appendBuildLog('✅ 镜像构建成功!')
        appendBuildLog(`🎉 镜像 ${buildForm.image_name} 已成功构建`)

        // 显示构建输出（如果有）
        if (response.data.output) {
          appendBuildLog('')
          appendBuildLog('📋 构建输出:')
          appendBuildLog(response.data.output)
        }

        ElMessage.success('镜像构建成功')
        buildDialogVisible.value = false
        resetBuildForm()
        await loadImages()
        await loadStatistics()
      } else {
        buildStatus.value = 'failed'
        buildProgress.value = 100

        // 显示详细的构建失败信息
        const errorMsg = response.data.message || '构建镜像失败'
        appendBuildLog('❌ 构建失败!')
        appendBuildLog('')
        appendBuildLog('🔍 错误详情:')
        appendBuildLog(errorMsg)

        console.error('构建失败详情:', errorMsg)
        ElMessage({
          message: '构建失败，请查看构建日志',
          type: 'error',
          duration: 5000,
          showClose: true
        })
      }
    } catch (error) {
      buildStatus.value = 'failed'
      buildProgress.value = 100

      appendBuildLog('❌ 构建异常!')
      appendBuildLog('')
      appendBuildLog('🔍 异常详情:')
      appendBuildLog(error.response?.data?.message || error.message)

      console.error('构建镜像失败:', error)
      ElMessage.error('构建镜像失败，请查看构建日志')
    } finally {
      building.value = false
    }
  } catch (error) {
    console.error('构建镜像操作失败:', error)
    ElMessage.error('构建镜像操作失败')
  }
}

// 文件复制操作
const addCopyFile = () => {
  buildForm.copy_files.push({ source: '', target: '' })
}

const removeCopyFile = (index) => {
  if (buildForm.copy_files.length > 1) {
    buildForm.copy_files.splice(index, 1)
  }
}

// ADD文件操作
const addAddFile = () => {
  buildForm.add_files.push({ source: '', target: '' })
}

const removeAddFile = (index) => {
  if (buildForm.add_files.length > 1) {
    buildForm.add_files.splice(index, 1)
  }
}

// 运行命令操作
const addRunCommand = () => {
  buildForm.run_commands.push('')
}

const removeRunCommand = (index) => {
  if (buildForm.run_commands.length > 1) {
    buildForm.run_commands.splice(index, 1)
  }
}

// 环境变量操作
const addEnvVar = () => {
  buildForm.env_vars.push({ key: '', value: '' })
}

const removeEnvVar = (index) => {
  if (buildForm.env_vars.length > 1) {
    buildForm.env_vars.splice(index, 1)
  }
}

// 标签操作
const addLabel = () => {
  buildForm.labels.push({ key: '', value: '' })
}

const removeLabel = (index) => {
  if (buildForm.labels.length > 1) {
    buildForm.labels.splice(index, 1)
  }
}

// 数据卷操作
const addVolume = () => {
  buildForm.volumes.push('')
}

const removeVolume = (index) => {
  if (buildForm.volumes.length > 1) {
    buildForm.volumes.splice(index, 1)
  }
}

// 端口操作
const addPort = () => {
  if (buildForm.new_port && !buildForm.expose_ports.includes(buildForm.new_port)) {
    buildForm.expose_ports.push(buildForm.new_port)
    buildForm.new_port = ''
  }
}

const removePort = (port) => {
  const index = buildForm.expose_ports.indexOf(port)
  if (index > -1) {
    buildForm.expose_ports.splice(index, 1)
  }
}

// 文件上传操作
const handleFileUpload = (file, fileList) => {
  const fileName = file.name
  const actualFile = file.raw || file // 兼容不同的文件对象格式

  console.log('上传文件:', fileName, '文件对象:', actualFile)

  const reader = new FileReader()
  reader.onload = (e) => {
    console.log('文件读取完成:', fileName, '数据长度:', e.target.result.byteLength)
    uploadedFiles.value.set(fileName, e.target.result)
  }
  reader.onerror = (e) => {
    console.error('文件读取失败:', fileName, e)
    ElMessage.error(`文件 ${fileName} 读取失败`)
  }

  if (actualFile) {
    reader.readAsArrayBuffer(actualFile)
  } else {
    console.error('无法获取文件对象:', file)
    ElMessage.error(`无法读取文件 ${fileName}`)
  }

  return false // 阻止自动上传
}

const removeUploadedFile = (fileName) => {
  uploadedFiles.value.delete(fileName)
}

// 构建日志相关函数
const appendBuildLog = (message) => {
  const timestamp = new Date().toLocaleTimeString()
  buildLog.value += `[${timestamp}] ${message}\n`

  // 自动滚动到底部
  nextTick(() => {
    if (buildLogRef.value) {
      buildLogRef.value.scrollTop = buildLogRef.value.scrollHeight
    }
  })
}

const clearBuildLog = () => {
  buildLog.value = ''
  buildStatus.value = 'ready'
  buildProgress.value = 0
}

// 重置构建表单
const resetBuildForm = () => {
  buildForm.base_image = 'nginx:alpine'
  buildForm.image_name = ''
  buildForm.maintainer = ''
  buildForm.work_dir = '/app'
  buildForm.copy_files = [{ source: '', target: '' }]
  buildForm.add_files = [{ source: '', target: '' }]
  buildForm.run_commands = ['']
  buildForm.env_vars = [{ key: '', value: '' }]
  buildForm.labels = [{ key: '', value: '' }]
  buildForm.volumes = ['']
  buildForm.expose_ports = []
  buildForm.cmd_command = ''
  buildForm.entrypoint_command = ''
  buildForm.new_port = ''
  uploadedFiles.value.clear()
}

const cleanupImages = async () => {
  if (!selectedServer.value) {
    ElMessage.warning('请先选择Docker服务器')
    return
  }

  try {
    await ElMessageBox.confirm(
      '确定要清理所有悬空镜像吗？此操作不可恢复。',
      '确认清理',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )

    loading.value = true

    try {
      const response = await dockerImageAPI.prune(selectedServer.value, { dangling_only: true })

      if (response.data.success) {
        ElMessage.success('悬空镜像清理完成')
        await loadImages()
        await loadStatistics()
      } else {
        ElMessage.error(response.data.message || '清理镜像失败')
      }
    } catch (error) {
      console.error('清理镜像失败:', error)
      ElMessage.error('清理镜像失败')
    } finally {
      loading.value = false
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('清理镜像操作失败:', error)
      ElMessage.error('清理失败')
    }
  }
}

const runContainer = async (image: any) => {
  if (!selectedServer.value) {
    ElMessage.warning('请先选择Docker服务器')
    return
  }

  try {
    // 打开运行容器对话框
    currentImage.value = image
    runDialogVisible.value = true
  } catch (error) {
    console.error('运行容器操作失败:', error)
    ElMessage.error('运行容器操作失败')
  }
}

// 提交运行容器
const submitRunContainer = async () => {
  if (!currentImage.value || !selectedServer.value) {
    ElMessage.warning('镜像信息不完整')
    return
  }

  try {
    loading.value = true

    const imageId = `${currentImage.value.repository}:${currentImage.value.tag}`

    try {
      // 处理表单数据
      const ports = runForm.ports ? runForm.ports.split('\n').filter(p => p.trim()) : []
      const volumes = runForm.volumes ? runForm.volumes.split('\n').filter(v => v.trim()) : []

      // 处理环境变量 - 从key:value数组转换为对象
      let env_vars = {}
      runForm.env_vars.forEach(envVar => {
        if (envVar.key && envVar.key.trim()) {
          env_vars[envVar.key.trim()] = envVar.value || ''
        }
      })

      const response = await dockerImageAPI.run(
        selectedServer.value,
        imageId,
        {
          container_name: runForm.container_name || undefined,
          ports: ports,
          volumes: volumes,
          env_vars: env_vars,
          command: runForm.command || undefined,
          args: runForm.args || undefined,
          restart_policy: runForm.restart_policy,
          auto_remove: runForm.auto_remove,
          privileged: runForm.privileged,
          user: runForm.user || undefined,
          working_dir: runForm.working_dir || undefined,
          hostname: runForm.hostname || undefined,
          network_mode: runForm.network_mode,
          memory_limit: runForm.memory_limit || undefined,
          cpu_limit: runForm.cpu_limit || undefined
        }
      )

      if (response.data.success) {
        ElMessage.success('容器创建并启动成功')
        runDialogVisible.value = false
        resetRunForm()
      } else {
        ElMessage.error(response.data.message || '创建容器失败')
      }
    } catch (error) {
      console.error('创建容器失败:', error)
      ElMessage.error('创建容器失败')
    } finally {
      loading.value = false
    }
  } catch (error) {
    console.error('运行容器操作失败:', error)
    ElMessage.error('运行容器操作失败')
  }
}

// 运行容器环境变量操作
const addRunEnvVar = () => {
  runForm.env_vars.push({ key: '', value: '' })
}

const removeRunEnvVar = (index) => {
  if (runForm.env_vars.length > 1) {
    runForm.env_vars.splice(index, 1)
  }
}

// 加载网络列表
const loadNetworksForSelect = async () => {
  if (!selectedServer.value || availableNetworks.value.length > 0) return

  try {
    const { dockerNetworkAPI } = await import('@/api/docker')
    const response = await dockerNetworkAPI.getNetworks(selectedServer.value)
    if (response.data.success) {
      availableNetworks.value = response.data.networks || []
    } else {
      console.error('加载网络列表失败:', response.data.message)
      availableNetworks.value = []
    }
  } catch (error) {
    console.error('加载网络列表失败:', error)
    availableNetworks.value = []
  }
}

// 重置运行容器表单
const resetRunForm = () => {
  runForm.container_name = ''
  runForm.ports = ''
  runForm.volumes = ''
  runForm.env_vars = [{ key: '', value: '' }]
  runForm.command = ''
  runForm.args = ''
  runForm.restart_policy = 'no'
  runForm.auto_remove = false
  runForm.privileged = false
  runForm.user = ''
  runForm.working_dir = ''
  runForm.hostname = ''
  runForm.network_mode = 'default'
  runForm.memory_limit = ''
  runForm.cpu_limit = ''
}

const tagImage = async (image: any) => {
  if (!selectedServer.value) {
    ElMessage.warning('请先选择Docker服务器')
    return
  }

  // 设置当前镜像和默认标签
  currentImage.value = image
  tagForm.target_image = `${image.repository}:new-tag`
  tagDialogVisible.value = true
}

// 提交标签镜像
const submitTagImage = async () => {
  if (!tagForm.target_image) {
    ElMessage.warning('镜像标签不能为空')
    return
  }

  try {
    loading.value = true

    const imageId = `${currentImage.value.repository}:${currentImage.value.tag}`

    try {
      const response = await dockerImageAPI.tag(selectedServer.value, imageId, { target_image: tagForm.target_image })

      if (response.data.success) {
        ElMessage.success('镜像标签添加成功')
        tagDialogVisible.value = false
        resetTagForm()
        await loadImages()
      } else {
        ElMessage.error(response.data.message || '添加镜像标签失败')
      }
    } catch (error) {
      console.error('添加镜像标签失败:', error)
      ElMessage.error('添加镜像标签失败')
    } finally {
      loading.value = false
    }
  } catch (error) {
    console.error('添加镜像标签操作失败:', error)
    ElMessage.error('添加镜像标签操作失败')
  }
}

// 重置标签表单
const resetTagForm = () => {
  tagForm.target_image = ''
}

const exportImage = async (image: any) => {
  if (!selectedServer.value) {
    ElMessage.warning('请先选择Docker服务器')
    return
  }

  // 设置当前镜像和默认导出路径
  currentImage.value = image
  exportForm.export_type = 'server'
  exportForm.output_file = `/tmp/${image.repository.replace('/', '_')}_${image.tag}.tar`
  exportDialogVisible.value = true
}

// 提交导出镜像
const submitExportImage = async () => {
  if (exportForm.export_type === 'server' && !exportForm.output_file) {
    ElMessage.warning('导出文件路径不能为空')
    return
  }

  try {
    loading.value = true

    const imageId = `${currentImage.value.repository}:${currentImage.value.tag}`

    try {
      if (exportForm.export_type === 'download') {
        // 下载到本地
        const response = await dockerImageAPI.downloadImage(selectedServer.value, imageId)

        if (response.data.success) {
          // 使用request工具直接下载文件
          const { default: request } = await import('@/utils/request')
          const downloadResponse = await request({
            url: response.data.download_url,
            method: 'get',
            responseType: 'blob'
          })

          // 使用正确的文件名
          const filename = response.data.filename || `${currentImage.value.repository.replace('/', '_')}_${currentImage.value.tag}.tar`

          // 创建Blob下载链接
          const blob = downloadResponse.data
          const url = window.URL.createObjectURL(blob)
          const link = document.createElement('a')
          link.href = url
          link.download = filename
          link.style.display = 'none'
          document.body.appendChild(link)
          link.click()
          window.URL.revokeObjectURL(url)
          document.body.removeChild(link)

          ElMessage.success(`镜像下载已开始: ${filename}`)
          exportDialogVisible.value = false
          resetExportForm()
        } else {
          ElMessage.error(response.data.message || '下载镜像失败')
        }
      } else {
        // 导出到服务器 - 显示进度条
        exportDialogVisible.value = false
        exportProgressVisible.value = true
        exportImageName.value = imageId
        exportProgress.value = 0
        exportStatus.value = '准备导出镜像...'

        // 模拟导出进度
        const progressInterval = setInterval(() => {
          if (exportProgress.value < 90) {
            exportProgress.value += Math.random() * 10
            if (exportProgress.value < 30) {
              exportStatus.value = '正在读取镜像层...'
            } else if (exportProgress.value < 60) {
              exportStatus.value = '正在压缩镜像数据...'
            } else if (exportProgress.value < 90) {
              exportStatus.value = '正在写入文件...'
            }
          }
        }, 500)

        try {
          const response = await dockerImageAPI.export(selectedServer.value, imageId, { output_file: exportForm.output_file })

          clearInterval(progressInterval)

          if (response.data.success) {
            exportProgress.value = 100
            exportStatus.value = '导出完成！'

            setTimeout(() => {
              exportProgressVisible.value = false
              ElMessage.success(`镜像导出成功到: ${response.data.output_file || exportForm.output_file}`)
              resetExportForm()
            }, 1500)
          } else {
            exportProgressVisible.value = false
            ElMessage.error(response.data.message || '导出镜像失败')
          }
        } catch (error) {
          clearInterval(progressInterval)
          exportProgressVisible.value = false
          throw error
        }
      }
    } catch (error) {
      console.error('导出镜像失败:', error)
      ElMessage.error('导出镜像失败')
    } finally {
      loading.value = false
    }
  } catch (error) {
    console.error('导出镜像操作失败:', error)
    ElMessage.error('导出镜像操作失败')
  }
}

// 重置导出表单
const resetExportForm = () => {
  exportForm.export_type = 'server'
  exportForm.output_file = ''
}

const inspectImage = async (image: any) => {
  if (!selectedServer.value) {
    ElMessage.warning('请先选择Docker服务器')
    return
  }

  try {
    // 保存当前镜像信息
    currentInspectImage.value = image

    // 显示详情对话框
    inspectDialogVisible.value = true
    inspectDialogTitle.value = `镜像 ${image.repository}:${image.tag} 详细信息`

    // 清空之前的内容
    inspectContent.value = '正在加载镜像详细信息...'

    // 获取镜像详细信息
    await refreshInspect()
  } catch (error) {
    console.error('获取镜像详细信息操作失败:', error)
    ElMessage.error('获取镜像详细信息操作失败')
  }
}

// 刷新inspect内容
const refreshInspect = async () => {
  if (!currentInspectImage.value || !selectedServer.value) {
    return
  }

  try {
    const imageId = `${currentInspectImage.value.repository}:${currentInspectImage.value.tag}`
    const response = await dockerImageAPI.inspect(selectedServer.value, imageId)

    if (response.data.success) {
      const imageInfo = response.data.data
      inspectContent.value = JSON.stringify(imageInfo, null, 2)
    } else {
      inspectContent.value = `获取镜像详细信息失败: ${response.data.message || '未知错误'}`
    }
  } catch (error) {
    console.error('获取镜像详细信息失败:', error)
    inspectContent.value = `获取镜像详细信息失败: ${error.message || '网络错误'}`
  }
}

// 复制inspect内容
const copyInspectContent = () => {
  if (inspectContent.value) {
    navigator.clipboard.writeText(inspectContent.value).then(() => {
      ElMessage.success('内容已复制到剪贴板')
    }).catch(() => {
      ElMessage.error('复制失败')
    })
  }
}

// 滚动到顶部
const scrollInspectToTop = () => {
  if (inspectContentRef.value) {
    inspectContentRef.value.scrollTop = 0
  }
}

// 滚动到底部
const scrollInspectToBottom = () => {
  if (inspectContentRef.value) {
    inspectContentRef.value.scrollTop = inspectContentRef.value.scrollHeight
  }
}

// 关闭详情对话框
const closeInspectDialog = () => {
  // 重置状态
  inspectContent.value = ''
  currentInspectImage.value = null

  // 关闭对话框
  inspectDialogVisible.value = false
}

const deleteImage = async (image: any) => {
  if (!selectedServer.value) {
    ElMessage.warning('请先选择Docker服务器')
    return
  }

  try {
    await ElMessageBox.confirm(
      `确定要删除镜像 "${image.repository}:${image.tag}" 吗？此操作不可恢复。`,
      '确认删除',
      {
        confirmButtonText: '删除',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )

    loading.value = true

    const imageId = `${image.repository}:${image.tag}`

    try {
      const response = await dockerImageAPI.removeImage(selectedServer.value, imageId)

      if (response.data.success) {
        ElMessage.success('镜像删除成功')
        await loadImages()
        await loadStatistics()
      } else {
        ElMessage.error(response.data.message || '删除镜像失败')
      }
    } catch (error) {
      console.error('删除镜像失败:', error)
      ElMessage.error('删除镜像失败')
    } finally {
      loading.value = false
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除镜像操作失败:', error)
      ElMessage.error('删除镜像操作失败')
    }
  }
}

// 工具函数
const formatSize = (size: number) => {
  if (!size) return '0 MB'
  const units = ['B', 'KB', 'MB', 'GB', 'TB']
  let index = 0
  while (size >= 1024 && index < units.length - 1) {
    size /= 1024
    index++
  }
  return `${size.toFixed(1)} ${units[index]}`
}

const formatTime = (time: string) => {
  if (!time) return '未知'
  return new Date(time).toLocaleString('zh-CN')
}
</script>

<style scoped>
/* 使用与Zabbix服务器配置页面完全相同的样式 */
.ansible-audit-container {
  min-height: 100vh;
  background: linear-gradient(
    135deg,
    rgba(0, 0, 0, 0.9) 0%,
    rgba(20, 20, 40, 0.95) 50%,
    rgba(0, 0, 0, 0.9) 100%
  );
  overflow-x: hidden;
}

.starry-background {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

.stars, .stars2, .stars3 {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: transparent;
}

.stars {
  background-image:
    radial-gradient(2px 2px at 20px 30px, #eee, transparent),
    radial-gradient(2px 2px at 40px 70px, rgba(255,255,255,0.8), transparent),
    radial-gradient(1px 1px at 90px 40px, #fff, transparent);
  background-repeat: repeat;
  background-size: 200px 100px;
  animation: zoom 20s infinite linear;
}

.stars2 {
  background-image:
    radial-gradient(1px 1px at 40px 60px, #fff, transparent),
    radial-gradient(1px 1px at 120px 10px, rgba(255,255,255,0.7), transparent);
  background-repeat: repeat;
  background-size: 300px 200px;
  animation: zoom 40s infinite linear;
}

.stars3 {
  background-image:
    radial-gradient(1px 1px at 10px 10px, rgba(255,255,255,0.5), transparent);
  background-repeat: repeat;
  background-size: 400px 300px;
  animation: zoom 60s infinite linear;
}

@keyframes zoom {
  from { transform: scale(1); }
  to { transform: scale(1.5); }
}

.audit-content {
  position: relative;
  z-index: 10;
  padding: 20px;
  max-width: 1400px;
  margin: 0 auto;
}

.glass-effect {
  background: rgba(164, 244, 186, 0.1);
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 12px;
  backdrop-filter: blur(20px);
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

.page-header {
  margin-bottom: 30px;
  padding: 30px;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 30px;
}

.title-section h1 {
  color: rgba(255, 255, 255, 0.95);
  font-size: 28px;
  font-weight: 600;
  margin: 0 0 8px 0;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

.title-section h1 i {
  color: #a4f4ba;
  margin-right: 12px;
}

.page-subtitle {
  color: rgba(255, 255, 255, 0.7);
  font-size: 14px;
  margin: 0;
}

.stats-section {
  display: flex;
  gap: 20px;
}

.stat-card {
  padding: 20px;
  text-align: center;
  min-width: 120px;
}

.stat-number {
  font-size: 24px;
  font-weight: bold;
  color: #a4f4ba;
  margin-bottom: 5px;
}

.stat-label {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.7);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.search-filters {
  margin-bottom: 30px;
  padding: 20px;
}

.search-form {
  margin: 0;
}

.audit-table-section {
  padding: 30px;
  margin-bottom: 30px;
}

.section-title {
  font-size: 18px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.95);
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.section-title i {
  color: #a4f4ba;
}

.config-name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
}

.config-name i {
  color: #00eaff;
}

.time-text, .image-id, .size-text {
  color: rgba(255, 255, 255, 0.7);
  font-size: 12px;
}

.image-id, .size-text {
  font-family: monospace;
}

.server-select {
  width: 200px;
  margin-right: 10px;
}

/* 工具栏按钮样式 - 完全照抄Zabbix服务器配置页面 */
.glass-button {
  background: rgba(164, 244, 186, 0.15) !important;
  border: 1px solid rgba(164, 244, 186, 0.3) !important;
  color: rgba(255, 255, 255, 0.9) !important;
  transition: all 0.3s ease !important;
  backdrop-filter: blur(10px) !important;
  border-radius: 8px !important;
  padding: 8px 16px !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) !important;

  &:hover {
    background: rgba(164, 244, 186, 0.25) !important;
    border-color: rgba(164, 244, 186, 0.5) !important;
    color: #ffffff !important;
    box-shadow: 0 4px 16px rgba(164, 244, 186, 0.2) !important;
  }

  i {
    margin-right: 6px !important;
    color: #00eaff !important;
  }

  /* 刷新按钮 - 紫色 */
  &.refresh-button {
    background: rgba(138, 43, 226, 0.2) !important;
    border-color: rgba(138, 43, 226, 0.4) !important;
    color: #ffffff !important;

    &:hover {
      background: rgba(138, 43, 226, 0.3) !important;
      border-color: rgba(138, 43, 226, 0.6) !important;
      box-shadow: 0 4px 16px rgba(138, 43, 226, 0.3) !important;
    }

    i {
      color: #8a2be2 !important;
    }
  }

  /* 推送按钮 - 紫色 */
  &.upload-button {
    background: rgba(155, 89, 182, 0.2) !important;
    border-color: rgba(155, 89, 182, 0.4) !important;
    color: #ffffff !important;

    &:hover {
      background: rgba(155, 89, 182, 0.3) !important;
      border-color: rgba(155, 89, 182, 0.6) !important;
      box-shadow: 0 4px 16px rgba(155, 89, 182, 0.3) !important;
    }

    i {
      color: #9b59b6 !important;
    }
  }

  /* 同步按钮 - 蓝色 */
  &.sync-button {
    background: rgba(59, 130, 246, 0.2) !important;
    border-color: rgba(59, 130, 246, 0.4) !important;
    color: #ffffff !important;

    &:hover {
      background: rgba(59, 130, 246, 0.3) !important;
      border-color: rgba(59, 130, 246, 0.6) !important;
      box-shadow: 0 4px 16px rgba(59, 130, 246, 0.3) !important;
    }

    i {
      color: #3b82f6 !important;
    }
  }

  /* 添加按钮 - 绿色 */
  &.add-button {
    background: rgba(34, 197, 94, 0.2) !important;
    border-color: rgba(34, 197, 94, 0.4) !important;
    color: #ffffff !important;

    &:hover {
      background: rgba(34, 197, 94, 0.3) !important;
      border-color: rgba(34, 197, 94, 0.6) !important;
      box-shadow: 0 4px 16px rgba(34, 197, 94, 0.3) !important;
    }

    i {
      color: #22c55e !important;
    }
  }

  /* 导入按钮 - 青色 */
  &.import-button {
    background: rgba(6, 182, 212, 0.2) !important;
    border-color: rgba(6, 182, 212, 0.4) !important;
    color: #ffffff !important;

    &:hover {
      background: rgba(6, 182, 212, 0.3) !important;
      border-color: rgba(6, 182, 212, 0.6) !important;
      box-shadow: 0 4px 16px rgba(6, 182, 212, 0.3) !important;
    }

    i {
      color: #06b6d4 !important;
    }
  }

  /* 删除按钮 - 红色 */
  &.delete-button {
    background: rgba(239, 68, 68, 0.2) !important;
    border-color: rgba(239, 68, 68, 0.4) !important;
    color: #ffffff !important;

    &:hover {
      background: rgba(239, 68, 68, 0.3) !important;
      border-color: rgba(239, 68, 68, 0.6) !important;
      box-shadow: 0 4px 16px rgba(239, 68, 68, 0.3) !important;
    }

    i {
      color: #ef4444 !important;
    }
  }
}

/* 表格样式 */
:deep(.audit-table) {
  background: transparent !important;

  .el-table__header {
    background: rgba(164, 244, 186, 0.1) !important;
  }

  .el-table__header th {
    background: transparent !important;
    border-bottom: 1px solid rgba(164, 244, 186, 0.3) !important;
    color: rgba(255, 255, 255, 0.9) !important;
    font-weight: 600 !important;
  }

  .el-table__body tr {
    background: transparent !important;

    &:hover {
      background: rgba(164, 244, 186, 0.05) !important;
    }
  }

  .el-table__body td {
    border-bottom: 1px solid rgba(164, 244, 186, 0.1) !important;
    color: rgba(255, 255, 255, 0.8) !important;
  }
}

.action-buttons {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: nowrap;
}

.action-buttons .glass-button {
  padding: 8px 16px !important;
  font-size: 12px;
  white-space: nowrap;
  width: auto !important;
  min-width: 80px !important;
}

/* 表单提示样式 */
.form-tip {
  font-size: 12px;
  color: rgba(164, 244, 186, 0.7);
  margin-top: 4px;
  margin-left: 2px;
}

/* 拉取镜像预览样式 */
.pull-preview {
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 8px;
  padding: 12px 16px;
  margin-top: 10px;
  margin-bottom: 10px;
}

.preview-label {
  color: rgba(164, 244, 186, 0.9);
  font-size: 14px;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.preview-content {
  background: rgba(0, 0, 0, 0.5);
  border-radius: 4px;
  padding: 10px;
  font-family: 'Courier New', monospace;
  color: #a4f4ba;
  overflow-x: auto;
}

.registry-option {
  display: flex;
  align-items: center;
  gap: 8px;
}

.registry-option i {
  color: #a4f4ba;
}

.current-image {
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 4px;
  padding: 8px 12px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: 'Courier New', monospace;
  color: #a4f4ba;
}

.current-image i {
  color: #a4f4ba;
}

/* 详情对话框样式 */
.inspect-dialog {
  --el-dialog-bg-color: rgba(26, 26, 26, 0.95);
  --el-dialog-border-radius: 12px;
}

.inspect-dialog .el-dialog__header {
  padding: 0;
  border-bottom: 1px solid rgba(164, 244, 186, 0.2);
}

.inspect-dialog .el-dialog__body {
  padding: 0;
  background: #0a0a0a;
}

.inspect-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  background: rgba(26, 26, 26, 0.95);
  border-bottom: 1px solid rgba(164, 244, 186, 0.2);
}

.inspect-title {
  display: flex;
  align-items: center;
  gap: 10px;
  color: #a4f4ba;
  font-size: 16px;
  font-weight: 500;
}

.inspect-icon {
  color: #a4f4ba;
  font-size: 18px;
}

.inspect-controls {
  display: flex;
  gap: 8px;
}

.inspect-content {
  height: 70vh;
  overflow-y: auto;
  background: #0a0a0a;
  padding: 0;
}

.inspect-pre {
  margin: 0;
  padding: 20px;
  background: #0a0a0a;
  color: #a4f4ba;
  font-family: 'Courier New', monospace;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* 导出选项样式 */
.export-type-group {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.export-radio {
  width: 100%;
  margin: 0;
  height: auto;
}

.export-radio .el-radio__input {
  position: absolute;
  top: 16px;
  left: 16px;
  z-index: 1;
}

.export-radio .el-radio__label {
  padding-left: 0;
  width: 100%;
}

.export-option {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 16px 16px 16px 50px;
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.3);
  transition: all 0.3s ease;
  width: 100%;
  cursor: pointer;
  position: relative;
}

.export-radio:hover .export-option {
  border-color: rgba(164, 244, 186, 0.4);
  background: rgba(0, 0, 0, 0.5);
}

.export-radio.is-checked .export-option {
  border-color: #a4f4ba;
  background: rgba(164, 244, 186, 0.1);
}

.export-option i {
  font-size: 20px;
  color: #a4f4ba;
  min-width: 20px;
  margin-top: 2px;
}

.export-option-content {
  flex: 1;
}

.export-option-title {
  color: #a4f4ba;
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 4px;
}

.export-option-desc {
  color: rgba(164, 244, 186, 0.7);
  font-size: 12px;
  line-height: 1.4;
}

/* 拉取进度样式 */
.pull-progress-container {
  padding: 20px 0;
}

.pull-image-info {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
  padding: 12px;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 8px;
  border: 1px solid rgba(164, 244, 186, 0.2);
}

.pull-icon {
  font-size: 20px;
  color: #a4f4ba;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% { opacity: 1; }
  50% { opacity: 0.5; }
  100% { opacity: 1; }
}

.pull-image-name {
  color: #a4f4ba;
  font-family: 'Courier New', monospace;
  font-size: 14px;
  font-weight: 500;
}

.pull-progress-wrapper {
  margin-bottom: 20px;
}

.pull-progress-bar {
  margin-bottom: 12px;
}

.pull-progress-bar .el-progress-bar__outer {
  background-color: rgba(0, 0, 0, 0.5) !important;
  border: 1px solid rgba(164, 244, 186, 0.2);
}

.pull-progress-bar .el-progress-bar__inner {
  background: linear-gradient(90deg, #a4f4ba, #00eaff) !important;
}

.pull-status {
  color: rgba(164, 244, 186, 0.8);
  font-size: 14px;
  text-align: center;
  margin-top: 8px;
}

.pull-tips {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  background: rgba(164, 244, 186, 0.1);
  border-radius: 6px;
  border: 1px solid rgba(164, 244, 186, 0.2);
  color: rgba(164, 244, 186, 0.8);
  font-size: 12px;
}

.pull-tips i {
  color: #a4f4ba;
}

/* 导出进度样式 */
.export-progress-container {
  padding: 20px 0;
}

.export-image-info {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
  padding: 12px;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 8px;
  border: 1px solid rgba(164, 244, 186, 0.2);
}

.export-icon {
  font-size: 20px;
  color: #a4f4ba;
  animation: pulse 2s infinite;
}

.export-image-name {
  color: #a4f4ba;
  font-family: 'Courier New', monospace;
  font-size: 14px;
  font-weight: 500;
}

.export-progress-wrapper {
  margin-bottom: 20px;
}

.export-progress-bar {
  margin-bottom: 8px;
}

.export-progress-text {
  color: rgba(164, 244, 186, 0.8);
  font-size: 14px;
  text-align: center;
  margin-top: 8px;
}

.export-tips {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  background: rgba(164, 244, 186, 0.1);
  border-radius: 6px;
  border: 1px solid rgba(164, 244, 186, 0.2);
  color: rgba(164, 244, 186, 0.8);
  font-size: 12px;
}

.export-tips i {
  color: #a4f4ba;
}

/* 环境变量样式 */
.env-vars-container {
  width: 100%;
}

.env-var-item {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}

.env-key-input {
  flex: 1;
  min-width: 150px;
}

.env-separator {
  color: #a4f4ba;
  font-weight: bold;
  font-size: 16px;
  min-width: 20px;
  text-align: center;
}

.env-value-input {
  flex: 1.5;
  min-width: 200px;
}

.env-remove-btn {
  min-width: 36px !important;
  padding: 8px !important;
}

.env-add-btn {
  width: 100%;
  margin-top: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.env-add-btn i {
  font-size: 12px;
}

/* 运行容器标签页样式 */
.run-container-tabs {
  --el-tabs-header-height: 50px;
}

.run-container-tabs .el-tabs__header {
  background: rgba(0, 0, 0, 0.3);
  border-radius: 8px 8px 0 0;
  margin: 0;
  border-bottom: 1px solid rgba(164, 244, 186, 0.2);
}

.run-container-tabs .el-tabs__nav-wrap {
  padding: 0 20px;
}

.run-container-tabs .el-tabs__item {
  color: rgba(164, 244, 186, 0.7);
  border: none;
  padding: 0 20px;
  height: 50px;
  line-height: 50px;
}

.run-container-tabs .el-tabs__item:hover {
  color: #a4f4ba;
}

.run-container-tabs .el-tabs__item.is-active {
  color: #a4f4ba;
  background: rgba(164, 244, 186, 0.1);
}

.run-container-tabs .el-tabs__active-bar {
  background-color: #a4f4ba;
}

.run-container-tabs .el-tabs__content {
  padding: 20px 0;
  max-height: 60vh;
  overflow-y: auto;
}

/* 运行选项样式 */
.run-options {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
}

.run-option-checkbox {
  width: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
}

.run-option-checkbox .el-checkbox {
  width: 100%;
  display: flex;
  align-items: flex-start;
  padding: 16px;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 6px;
  transition: all 0.3s ease;
  box-sizing: border-box;
  min-height: 60px;
}

.run-option-checkbox .el-checkbox:hover {
  border-color: rgba(164, 244, 186, 0.4);
  background: rgba(0, 0, 0, 0.5);
}

.run-option-checkbox .el-checkbox__input {
  margin-right: 12px;
  margin-top: 2px;
  flex-shrink: 0;
}

.run-option-checkbox .el-checkbox__label {
  padding-left: 0 !important;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 100%;
  flex: 1;
  line-height: 1.4;
}

.option-label {
  color: #a4f4ba;
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 4px;
  display: block;
  width: 100%;
}

.option-desc {
  color: rgba(164, 244, 186, 0.7);
  font-size: 12px;
  line-height: 1.4;
  display: block;
  width: 100%;
  word-wrap: break-word;
  overflow-wrap: break-word;
}

/* 构建镜像对话框样式 */
.build-image-container {
  display: flex;
  gap: 30px;
  height: 700px;
}

.build-config-section {
  flex: 2;
  overflow-y: auto;
  padding-right: 10px;
}

/* 构建日志样式 */
.build-log-container {
  height: 500px;
  display: flex;
  flex-direction: column;
}

.build-log-header {
  margin-bottom: 15px;
  padding: 15px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.build-info {
  display: flex;
  align-items: center;
  gap: 15px;
  margin-bottom: 10px;
}

.build-image-name {
  font-size: 16px;
  font-weight: bold;
  color: #409eff;
}

.build-status {
  padding: 4px 12px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: bold;
}

.build-status.ready {
  background: rgba(144, 147, 153, 0.2);
  color: #909399;
}

.build-status.building {
  background: rgba(64, 158, 255, 0.2);
  color: #409eff;
}

.build-status.success {
  background: rgba(103, 194, 58, 0.2);
  color: #67c23a;
}

.build-status.failed {
  background: rgba(245, 108, 108, 0.2);
  color: #f56c6c;
}

.build-progress {
  margin-top: 5px;
}

.build-log-content {
  flex: 1;
  background: #000;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  overflow-y: auto;
  padding: 15px;
}

.build-log-text {
  color: #00ff00;
  font-family: 'Courier New', monospace;
  font-size: 13px;
  line-height: 1.4;
  margin: 0;
  white-space: pre-wrap;
  word-wrap: break-word;
}

.dockerfile-preview-section {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.preview-header {
  margin-bottom: 15px;
}

.preview-header h4 {
  color: #a4f4ba;
  font-size: 16px;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.dockerfile-content {
  flex: 1;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 8px;
  padding: 15px;
  overflow-y: auto;
}

.dockerfile-content pre {
  color: #a4f4ba;
  font-family: 'Courier New', monospace;
  font-size: 13px;
  line-height: 1.5;
  margin: 0;
  white-space: pre-wrap;
}

/* 文件复制样式 */
.copy-files-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.copy-file-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.copy-source-input,
.copy-target-input {
  flex: 1;
}

.copy-arrow {
  color: #a4f4ba;
  font-weight: bold;
  min-width: 20px;
  text-align: center;
}

.copy-remove-btn,
.run-remove-btn {
  min-width: 32px;
}

.copy-add-btn,
.run-add-btn {
  align-self: flex-start;
  margin-top: 5px;
}

/* 运行命令样式 */
.run-commands-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.run-command-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.run-command-input {
  flex: 1;
}

/* 端口样式 */
.expose-ports-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ports-input-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.port-input {
  flex: 1;
}

.port-add-btn {
  min-width: 60px;
}

.ports-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.port-tag {
  background: rgba(164, 244, 186, 0.2) !important;
  border-color: rgba(164, 244, 186, 0.4) !important;
  color: #a4f4ba !important;
}

.port-tag .el-tag__close {
  color: #a4f4ba !important;
}

.port-tag .el-tag__close:hover {
  background: rgba(164, 244, 186, 0.3) !important;
}

/* 标签样式 */
.labels-container,
.env-vars-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.label-item,
.env-var-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.label-key-input,
.label-value-input,
.env-key-input,
.env-value-input {
  flex: 1;
}

.label-separator,
.env-separator {
  color: #a4f4ba;
  font-weight: bold;
  min-width: 20px;
  text-align: center;
}

.label-remove-btn,
.env-remove-btn {
  min-width: 32px;
}

.label-add-btn,
.env-add-btn {
  align-self: flex-start;
  margin-top: 5px;
}

/* ADD文件样式 */
.add-files-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.add-file-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.add-source-input,
.add-target-input {
  flex: 1;
}

.add-arrow {
  color: #a4f4ba;
  font-weight: bold;
  min-width: 20px;
  text-align: center;
}

.add-remove-btn {
  min-width: 32px;
}

.add-add-btn {
  align-self: flex-start;
  margin-top: 5px;
}

/* 数据卷样式 */
.volumes-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.volume-item {
  display: flex;
  align-items: center;
  gap: 10px;
}

.volume-input {
  flex: 1;
}

.volume-remove-btn {
  min-width: 32px;
}

.volume-add-btn {
  align-self: flex-start;
  margin-top: 5px;
}

/* 文件上传样式 */
.file-upload-container {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.uploaded-files-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.uploaded-file-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 6px;
}

.uploaded-file-item i {
  color: #a4f4ba;
}

.uploaded-file-item .filename {
  flex: 1;
  color: #a4f4ba;
  font-size: 14px;
}

.file-remove-btn {
  min-width: 28px;
  height: 28px;
}

.glass-upload .el-upload {
  width: 100%;
}

.glass-upload .el-button {
  width: 100%;
}

/* 推送镜像对话框样式 */
.push-info {
  margin-bottom: 20px;
  padding: 12px;
  background: rgba(0, 234, 255, 0.1);
  border: 1px solid rgba(0, 234, 255, 0.2);
  border-radius: 8px;
}

.info-item {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #00eaff;
  font-size: 14px;
}

.push-preview {
  margin-top: 20px;
  padding: 16px;
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 8px;
}

.push-preview h4 {
  color: #00eaff;
  margin: 0 0 12px 0;
  font-size: 14px;
}

.preview-info {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.preview-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.preview-item .label {
  color: rgba(255, 255, 255, 0.8);
  font-size: 12px;
  min-width: 60px;
}

.preview-item code {
  background: rgba(164, 244, 186, 0.1);
  color: #a4f4ba;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 12px;
  font-family: 'Courier New', monospace;
}

.preview-commands {
  margin-top: 8px;
}

.preview-commands .label {
  color: rgba(255, 255, 255, 0.8);
  font-size: 12px;
  display: block;
  margin-bottom: 8px;
}

.command-line {
  margin-bottom: 4px;
}

.command-line code {
  background: rgba(0, 0, 0, 0.3);
  color: #a4f4ba;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 11px;
  font-family: 'Courier New', monospace;
  display: block;
  word-break: break-all;
}

/* 标签选项样式 */
.tag-option {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.tag-name {
  color: #a4f4ba;
  font-weight: 500;
}

.tag-size {
  color: rgba(255, 255, 255, 0.6);
  font-size: 12px;
}

/* 镜像选择样式 */
.image-option {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}

.image-name {
  font-weight: 500;
  color: rgba(164, 244, 186, 0.9);
  flex: 1;
}

.image-size {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.6);
}

.image-tag-badge {
  font-size: 10px;
  padding: 2px 6px;
  background: rgba(255, 193, 7, 0.2);
  color: #ffc107;
  border-radius: 4px;
  border: 1px solid rgba(255, 193, 7, 0.3);
}
</style>
